/// <reference path="../../index.d.ts" />
import type { PublicLitElement as LitElement } from "@arcgis/lumina";
import type { InteractionMode, Scale, SelectionMode } from "../interfaces.js";
import type { ItemData } from "../calcite-list-item/interfaces.js";
import type { NumberingSystem } from "../../utils/locale.js";
import type { ListItem } from "../calcite-list-item/customElement.js";
import type { SelectionAppearance } from "./resources.js";
import type { ListDisplayMode, ListDragDetail } from "./interfaces.js";

/**
 * A general purpose list that enables users to construct list items that conform to Calcite styling.
 *
 * @cssproperty [--calcite-list-background-color] - Specifies the component's background color.
 * @slot  - A slot for adding `calcite-list-item` and `calcite-list-item-group` elements.
 * @slot [empty-content] - A slot for adding content to display when the component has no `calcite-list-item`s.
 * @slot [filter-actions-start] - A slot for adding actionable `calcite-action` elements before the filter component.
 * @slot [filter-actions-end] - A slot for adding actionable `calcite-action` elements after the filter component.
 * @slot [filter-no-results] - When `filterEnabled` is `true`, a slot for adding content to display when no results are found.
 */
export abstract class List extends LitElement {
  /** When provided, the method will be called to determine whether the element can move from the list. */
  accessor canPull: (detail: ListDragDetail) => boolean | "clone";
  /** When provided, the method will be called to determine whether the element can be added from another list. */
  accessor canPut: (detail: ListDragDetail) => boolean;
  /**
   * When `true`, interaction is prevented and the component is displayed with lower opacity.
   *
   * @default false
   */
  accessor disabled: boolean;
  /**
   * Specifies the nesting behavior of `calcite-list-item`s, where
   *
   * `"flat"` displays `calcite-list-item`s in a uniform list, and
   *
   * `"nested"` displays `calcite-list-item`s under their parent element.
   *
   *  The parent component's behavior should follow throughout its child elements.
   *
   * @default "flat"
   */
  accessor displayMode: ListDisplayMode;
  /**
   * When `true`, `calcite-list-item`s are sortable via a draggable button.
   *
   * @default false
   */
  accessor dragEnabled: boolean;
  /** The currently filtered `calcite-list-item` data. */
  get filteredData(): ItemData[];
  /** The currently filtered `calcite-list-item`s. */
  get filteredItems(): ListItem[];
  /**
   * When `true`, an input appears at the top of the component that can be used by end users to filter `calcite-list-item`s.
   *
   * @default false
   */
  accessor filterEnabled: boolean;
  /** Specifies an accessible name for the filter input field. */
  accessor filterLabel: string | undefined;
  /** Specifies placeholder text for the component's filter input field. */
  accessor filterPlaceholder: string | undefined;
  /**
   * Specifies a function to handle filtering.
   *
   * @example
   * myList.filterPredicate = (myListItem) => {
   *   // returns true to show the list item if some condition is met
   *   return myListItem.label.includes("someValue");
   * };
   */
  accessor filterPredicate: ((item: ListItem) => boolean) | undefined;
  /** Specifies the properties to match against when filtering. If not set, all properties will be matched (`description`, `label`, `metadata`, and the `calcite-list-item-group`'s `heading`). */
  accessor filterProps: string[] | undefined;
  /**
   * Text for the component's filter input field.
   *
   * @default ""
   */
  accessor filterText: string;
  /**
   * The component's group identifier.
   *
   * To drag elements from one list into another, both lists must have the same group value.
   */
  accessor group: string | undefined;
  /**
   * Specifies the interaction mode of the component, where
   *
   * `"interactive"` allows interaction styling and pointer changes on hover,
   *
   * `"static"` does not allow interaction styling and pointer changes on hover -
   *
   * the `"static"` value should only be used when `selectionMode` is `"none"`.
   *
   * @default "interactive"
   */
  accessor interactionMode: InteractionMode;
  /**
   * Specifies an accessible label for the component.
   *
   * When `dragEnabled` is `true` and multiple list sorting is enabled with `group`, specifies the component's name for dragging between lists.
   *
   * @required
   */
  accessor label: string;
  /**
   * When `true`, a busy indicator is displayed.
   *
   * @default false
   */
  accessor loading: boolean;
  /** Overrides individual strings used by the component. */
  accessor messageOverrides: {
      filterEnabled?: string;
      total?: string;
  };
  /** Specifies the Unicode numeral system used by the component for localization. */
  accessor numberingSystem: NumberingSystem | undefined;
  /**
   * Specifies the size of the component.
   *
   * @default "m"
   */
  accessor scale: Scale;
  /** The currently selected items. */
  get selectedItems(): ListItem[];
  /**
   * Specifies the selection appearance, where
   *
   * `"icon"` displays a checkmark or dot,
   *
   * `"border"` [Deprecated] - Use `"highlight"` instead - displays a border, or
   *
   * `"highlight"` displays background highlight.
   *
   * @default "icon"
   */
  accessor selectionAppearance: Extract<"icon" | "border" | "highlight", SelectionAppearance>;
  /**
   * Specifies the selection mode of the component, where:
   *
   * `"multiple"` allows any number of selections,
   *
   * `"single"` allows only one selection,
   *
   * `"single-persist"` allows one selection and prevents de-selection, and
   *
   * `"none"` does not allow any selections.
   *
   * @default "none"
   */
  accessor selectionMode: Extract<"none" | "multiple" | "single" | "single-persist", SelectionMode>;
  /**
   * When `true`, and a `group` is defined, `calcite-list-item`s are no longer sortable.
   *
   * @default false
   */
  accessor sortDisabled: boolean;
  /**
   * Sets focus on the component's first focusable element.
   *
   * @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
   * @see [MDN - focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
   */
  setFocus(options?: FocusOptions): Promise<void>;
  /** Fires when the component's selected items have changed. */
  readonly calciteListChange: import("@arcgis/lumina").TargetedEvent<this, void>;
  /** Fires when the component's dragging has ended. */
  readonly calciteListDragEnd: import("@arcgis/lumina").TargetedEvent<this, ListDragDetail>;
  /** Fires when the component's dragging has started. */
  readonly calciteListDragStart: import("@arcgis/lumina").TargetedEvent<this, ListDragDetail>;
  /** Fires when the component's filter has changed. */
  readonly calciteListFilter: import("@arcgis/lumina").TargetedEvent<this, void>;
  /**
   * Fires when a user attempts to move an element using the sort menu and 'canPut' or 'canPull' returns falsy.
   *
   * @deprecated in v3.3.0, removal target v6.0.0 - No longer necessary.
   */
  readonly calciteListMoveHalt: import("@arcgis/lumina").TargetedEvent<this, ListDragDetail>;
  /** Fires when the component's item order changes. */
  readonly calciteListOrderChange: import("@arcgis/lumina").TargetedEvent<this, ListDragDetail>;
  readonly "@eventTypes": {
    calciteListChange: List["calciteListChange"]["detail"];
    calciteListDragEnd: List["calciteListDragEnd"]["detail"];
    calciteListDragStart: List["calciteListDragStart"]["detail"];
    calciteListFilter: List["calciteListFilter"]["detail"];
    calciteListMoveHalt: List["calciteListMoveHalt"]["detail"];
    calciteListOrderChange: List["calciteListOrderChange"]["detail"];
  };
}