import { nothing, PropertyValues, TemplateResult } from "lit";
import '../../define/ui/ui-icon.js';
import '../../define/ui/ui-icon-button.js';
import { IconType } from "../../ui/icons/Icons.js";
import ApiElement from "../ApiElement.js";
export interface ISelectDetail {
    /**
     * The key of the selected item
     */
    key: string;
    /**
     * THe kind of the selected item
     */
    kind: string;
    /**
     * Optionally, the parent odf the selected item, if any.
     */
    parent?: string;
    /**
     * When applicable, the top object in the structure.
     */
    root?: string;
}
export interface IListItemRenderOptions {
    draggable?: boolean;
    parent?: string;
    disabled?: boolean;
    /**
     * Only relevant for parent list item.
     * When set it forces this icon to be rendered next to the toggle button.
     */
    parentIcon?: IconType;
    /**
     * When set is add the `data-root` attribute.
     * In principle, it represents a root object in the tree, if any.
     */
    root?: string;
}
/**
 * A base class for navigation elements helping creating specific implementation of the view.
 * The implementations sets their own properties with the data that are used to generate the view.
 *
 * The generated menu must have the following structure created by the implementations:
 *
 * ```html
 * <ul aria-label="..." aria-multiselectable="false">
 *  <li role="treeitem" data-key="..." data-kind="..." data-draggable="true|false">
 *    <div class="list-item-content"><span class="label" title="...">...</span></div>
 *  </li>
 *  <li role="treeitem" data-key="..." data-kind="..." data-draggable="true|false" aria-expanded="true|false" class="parent-item">
 *    <div class="list-item-content">
 *      <ui-icon icon="chevronRight" class="group-toggle-icon"></ui-icon>
 *      <span class="label" title="...">...</span>
 *    </div>
 *    <ul role="group" data-parent="..." ?hidden aria-hidden="true|false">
 *      <li role="treeitem" data-key="..." data-parent="..." data-kind="..." data-draggable="true|false">
 *        <div class="list-item-content">
 *          <ui-icon icon="..." class="item-icon"></ui-icon>
 *          <span class="label" title="...">...</span>
 *        </div>
 *      </li>
 *    </ul>
 *  </li>
 * </ul>
 * ```
 *
 * Additionally, the child element must include styles from './AppNavigation.styles.js`.
 *
 * Assumptions when running the menu:
 *
 * - all `li` items that do not have `aria-disabled` attribute are considered active tree items (learn more why not to use "disabled" attribute https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-disabled)
 * - all `li` elements have `data-key` and `data-kind` attributes set. Elements without these properties are ignored.
 * - all `ul` and `li` elements that have a parent also have `data-parent` with the value of the parent's key. When this is not set the element is considered a top level element.
 * - the implementations does not manage the `tabindex` of any item. Instead set the `_focusedItem` to the currently focused element and the base will manage the focus for you (after the update is complete).
 *
 * @fires select - Custom, non bubbling event when a selection is made. It has the `key` and `kind` properties on the detail panel with optional `parent` id.
 */
export default class AppNavigation extends ApiElement {
    /**
     * The list of keys of opened items with children. This should be clear each time
     * when the main data property change.
     */
    protected _opened: string[];
    /**
     * The key of the currently focused item.
     */
    protected _focused?: string;
    /**
     * The currently focused node.
     * In case there are headers in the list, this may not be a list item.
     */
    _focusedItem?: HTMLElement;
    /**
     * To be set in the child class constructor to configure whether a name change is possible.
     */
    protected _allowRename?: boolean;
    /**
     * The currently selected navigation item.
     * @attr
     */
    selected?: string;
    /**
     * When set it renders a name change input for the item.
     * This is the `key` of the object.
     *
     * Note, when the user finish editing the name it calls the `_commitName(key, kind, name)` method.
     * This requires the `_allowRename` property to be set to `true` in the constructor.
     * @attr
     */
    edited?: string;
    /**
     * When set it prohibits the element to make visual selection (via the css) when an item is selected.
     * This is helpful when one navigation can be visually references in multiple places (like split layout).
     * @attr
     */
    noVisualSelection?: boolean;
    /**
     * A reference to the currently rendered name input, if any.
     */
    protected _nameInput?: HTMLInputElement | null;
    /**
     * When set it adds a menu entry with the navigation label.
     * @attribute
     */
    label?: string;
    connectedCallback(): void;
    protected willUpdate(cp: PropertyValues<this>): void;
    protected updated(cp: PropertyValues<this>): void;
    protected _reset(): void;
    /**
     * This method is called when the `_focusedItem` property is updated.
     * It removes tabindex from the old element (if any) and sets tabindex and focuses on the new item (if any).
     * When there's no new item, it sets the `tabindex` on self.
     *
     * @param current The new focused element, if any
     * @param old The old focused element, if any.
     */
    protected _manageFocus(current?: HTMLElement, old?: HTMLElement): void;
    /**
     * Makes sure the node represented by the passed key is visible in the UI.
     * This opens all parents on the way up to the root and scrolls to the node, when needed.
     * @param key The key of the object to ensure visibility for.
     */
    ensureTreeVisibility(key: string): void;
    /**
     * Toggles a group of tree items.
     *
     * @param key The key of the group parent.
     */
    toggleGroup(key: string): void;
    /**
     * Allows to programmatically open a folder.
     * It opens all parents if they are not opened.
     * @param key The key of the folder to open.
     */
    openGroup(key: string): void;
    /**
     * Allows to programmatically close a folder.
     * @param key The key of the folder to open.
     */
    closeGroup(key: string): void;
    /**
     * A function to determine whether the passed Element is an active list item.
     *
     * @param node The Element to test
     * @returns true when the passed element is a `li` element and is not disabled.
     */
    protected _isValidListItem(node: Element): boolean;
    /**
     * Marks the item as currently focused.
     *
     * Note, focused item is not the same as selected item. Focus is reflected in the UI without changing the selection.
     *
     * Also note, this only sets the `_focused` and `_focusedItem` properties. After the element renders
     * the implementation should change the `tabindex` of the focused item to `0`.
     */
    protected _focusListItem(node: HTMLElement): void;
    /**
     * Finds a valid list item that is a parent to the current item.
     *
     * @param node The current node located somewhere in the tree.
     * @returns The nearest parent list item or undefined when not found.
     */
    protected _findParentListItem(node: HTMLElement): HTMLLIElement | undefined;
    /**
     * From a `<li>` it finds the last `<li>` descendant in the tree.
     *
     * ```html
     * <ul>
     *  <li> <-- this is the current node
     *    <div>...</div>
     *    <ul>
     *       <li>...</li>
     *       <li>  <-- this is the last list item.
     *          <div>...</div>
     *          <ul hidden> <- this is ignored.
     *            <li></li>
     *            <li></li>  <-- this is not the last list item because the parent list is hidden.
     *          </ul>
     *      </li>
     *    </ul>
     *  </li>
     * </ul>
     * ```
     *
     * @param node The current list item to find the last descendant for.
     * @returns The last list item or undefined.
     */
    protected _findLastDescendant(node: HTMLElement): HTMLElement | undefined;
    /**
     * Focuses on a list descendant of a folder item.
     * It does nothing when the `node` is not a folder item or the folder has no selectable children.
     *
     * @param node The node to use as a reference. The current focused node by default.
     * @returns true when focused on any of the descendants
     */
    protected _focusFirstDescendant(node?: HTMLElement | undefined): boolean;
    /**
     * Focuses on the next node relative to the passed node.
     *
     * @param node The node to use as a starting point. When not set it uses the currently focused node.
     * @returns true when focused on any of the next siblings
     */
    focusNextSibling(node?: HTMLElement | undefined): boolean;
    /**
     * Focuses on the previous node relative to the passed node.
     *
     * @param node The node to use as a starting point. When not set it uses the currently focused node.
     * @returns true when focused on any of the previous siblings
     */
    focusPreviousSibling(node?: HTMLElement | undefined): boolean;
    /**
     * Focuses on a first list item that accepts focus relative to the given node.
     *
     * @param node The node to use as a reference. The current focused node by default.
     * @returns true when focused on any of the parents
     */
    protected _focusFirstParent(node: HTMLElement): boolean;
    protected _findClosestListItem(e: Event): HTMLLIElement | undefined;
    /**
     * Dispatched the `select` custom event with the `key` and `kind` on the detail.
     *
     * @param key The key of the selected item.
     * @param kind The kind of the selected item
     * @param parent Optional parent item.
     */
    protected _notifySelection(key: string, kind: string, parent?: string, root?: string): void;
    /**
     * A handler for the `dragstart` event dispatched when the item is draggable.
     * Calls the `_setupDataTransfer()` if has valid target.
     */
    protected _itemDragStartHandler(e: DragEvent): void;
    /**
     * Sets the common properties on the `DataTransfer`. Implementations can override this method to add
     * own properties.
     */
    protected _setupDataTransfer(item: HTMLLIElement, dt: DataTransfer): void;
    protected _nameInputKeydown(e: KeyboardEvent): void;
    protected _commitNameHandler(e: Event): void;
    /**
     * This should be overwritten by the implementation that support name change.
     * Method called when the user request to change a name of an item.
     *
     * @param key The key of the item.
     * @param kind The kind of the item.
     * @param name THe new name.
     */
    protected _commitName(key: string, kind: string, name: string): void | Promise<void>;
    protected _dblClickHandler(e: Event): void;
    protected _clickHandler(e: Event): void;
    protected _keydownHandler(e: KeyboardEvent): void;
    protected renderLabel(): TemplateResult | typeof nothing;
    /**
     * Performs the default action of the currently focused node.
     * For parent nodes, it opens or closes the node.
     * In single-select trees, if the node has no children, selects the current node
     * if not already selected (which is the default action).
     */
    protected _itemEnterAction(node: HTMLElement): void;
    /**
     * 1. When focus is on a closed node, opens the node; focus does not move.
     * 2. When focus is on a open node, moves focus to the first child node.
     * 3. When focus is on an end node (a tree item with no children), does nothing.
     */
    protected _itemRightAction(node: HTMLElement): void;
    /**
     * 1. When focus is on an open node, closes the node.
     * 2. When focus is on a child node that is also either an end node or a closed node, moves focus to its parent node.
     * 3. When focus is on a closed `tree`, does nothing.
     */
    protected _itemLeftAction(node: HTMLElement): void;
    /**
     * Moves focus to the next node that is focusable without opening or closing a node.
     */
    protected _itemDownAction(node: HTMLElement): void;
    /**
     * Moves focus to the previous node that is focusable without opening or closing a node.
     */
    protected _itemUpAction(node: HTMLElement): void;
    protected _homeAction(): void;
    protected _endAction(): void;
    /**
     *
     * @param contents The children contents.
     * @returns A predefined template for the outer list element.
     */
    protected _outerListTemplate(contents: TemplateResult | TemplateResult[] | string): TemplateResult;
    protected _parentListItemTemplate(key: string, kind: string, label: string, children: TemplateResult | TemplateResult[] | string, opts?: IListItemRenderOptions): TemplateResult;
    protected parentListItemContentTemplate(label: string, opts?: IListItemRenderOptions): TemplateResult;
    protected _listItemTemplate(key: string, kind: string, label: string, content: TemplateResult | TemplateResult[] | string, opts?: IListItemRenderOptions): TemplateResult;
    protected _nameInputTemplate(key: string, kind: string, oldName?: string): TemplateResult;
    protected _itemContentTemplate(icon: IconType, label: string): TemplateResult;
}
//# sourceMappingURL=AppNavigationElement.d.ts.map