// Type definitions for agate/VirtualList

import { VirtualListBasicProps as ui_VirtualList_VirtualListBasicProps } from "@enact/ui/VirtualList";
import * as React from "react";
import { gridListItemSizeShape as ui_VirtualList_gridListItemSizeShape } from "@enact/ui/VirtualList";

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;

export interface VirtualListProps extends ui_VirtualList_VirtualListBasicProps {
  /**
 * Size of an item for the VirtualList; valid value is a number generally.
For different item size, value is an object that has  `minSize` 
and  `size`  as properties.
If the direction for the list is vertical, itemSize means the height of an item.
For horizontal, it means the width of an item.
 * 
 * Usage:
 * ```
<VirtualList itemSize={ri.scale(144)} />
```
 */
  itemSize: number | ui_VirtualList_itemSizesShape;
  /**
 * A callback function that receives a reference to the  `scrollTo`  feature.
 * 
 * Once received, the  `scrollTo`  method can be called as an imperative interface.
 * 
 * The  `scrollTo`  function accepts the following parameters:
 * *  {position: {x, y}} - Pixel value for x and/or y position
 * *  {align} - Where the scroll area should be aligned. Values are:
 `'left'` ,  `'right'` ,  `'top'` ,  `'bottom'` ,
 `'topleft'` ,  `'topright'` ,  `'bottomleft'` , and  `'bottomright'` .
 * *  {index} - Index of specific item. ( `0`  or positive integer)
This option is available for only  `VirtualList`  kind.
 * *  {node} - Node to scroll into view
 * *  {animate} - When  `true` , scroll occurs with animation. When  `false` , no
animation occurs.
 * *  {focus} - When  `true` , attempts to focus item after scroll. Only valid when scrolling
  by  `index`  or  `node` .
 * 
 * Note: Only specify one of:  `position` ,  `align` ,  `index`  or  `node`
 * 
 * Example:
 * ```
// If you set cbScrollTo prop like below;
cbScrollTo: (fn) => {this.scrollTo = fn;}
// You can simply call like below;
this.scrollTo({align: 'top'}); // scroll to the top
```
 */
  cbScrollTo?: Function;
  /**
   * The layout direction of the list.
   */
  direction?: "horizontal" | "vertical";
  /**
 * Allows 5-way navigation to the scrollbar controls. By default, 5-way will
not move focus to the scrollbar controls.
 */
  focusableScrollbar?: boolean;
  /**
   * Specifies how to show horizontal scrollbar.
   */
  horizontalScrollbar?: "auto" | "visible" | "hidden";
  /**
 * Unique identifier for the component.
 * 
 * When defined and when the  `VirtualList`  is within a  Panel  ,
the  `VirtualList`  will store its scroll position and restore that position when returning to
the  `Panel` .
 */
  id?: string;
  /**
 * Called when scrolling.
 * 
 * Passes  `scrollLeft` ,  `scrollTop` , and  `moreInfo` .
It is not recommended to set this prop since it can cause performance degradation.
Use  `onScrollStart`  or  `onScrollStop`  instead.
 */
  onScroll?: Function;
  /**
 * Called when scroll starts.
 * 
 * Passes  `scrollLeft` ,  `scrollTop` , and  `moreInfo` .
You can get firstVisibleIndex and lastVisibleIndex from VirtualList with  `moreInfo` .
 * 
 * Example:
 * ```
onScrollStart = ({scrollLeft, scrollTop, moreInfo}) => {
    const {firstVisibleIndex, lastVisibleIndex} = moreInfo;
    // do something with firstVisibleIndex and lastVisibleIndex
}

render = () => (
    <VirtualList
        ...
        onScrollStart={this.onScrollStart}
        ...
    />
)
```
 */
  onScrollStart?: Function;
  /**
 * Called when scroll stops.
 * 
 * Passes  `scrollLeft` ,  `scrollTop` , and  `moreInfo` .
You can get firstVisibleIndex and lastVisibleIndex from VirtualList with  `moreInfo` .
 * 
 * Example:
 * ```
onScrollStop = ({scrollLeft, scrollTop, moreInfo}) => {
    const {firstVisibleIndex, lastVisibleIndex} = moreInfo;
    // do something with firstVisibleIndex and lastVisibleIndex
}

render = () => (
    <VirtualList
        ...
        onScrollStop={this.onScrollStop}
        ...
    />
)
```
 */
  onScrollStop?: Function;
  /**
   * The ARIA role for the list.
   */
  role?: string;
  /**
   * Sets the hint string read when focusing the next button in the vertical scroll bar.
   */
  scrollDownAriaLabel?: string;
  /**
   * Sets the hint string read when focusing the previous button in the horizontal scroll bar.
   */
  scrollLeftAriaLabel?: string;
  /**
   * Specifies how to scroll.
   *
   * Valid values are:
   * *  `'translate'` ,
   * *  `'native'` .
   */
  scrollMode?: string;
  /**
   * Sets the hint string read when focusing the next button in the horizontal scroll bar.
   */
  scrollRightAriaLabel?: string;
  /**
   * Sets the hint string read when focusing the previous button in the vertical scroll bar.
   */
  scrollUpAriaLabel?: string;
  /**
   * Specifies how to show vertical scrollbar.
   *
   * Valid values are:
   * *  `'auto'` ,
   * *  `'visible'` , and
   * *  `'hidden'` .
   */
  verticalScrollbar?: "auto" | "visible" | "hidden";
  /**
 * When it's  `true`  and the spotlight focus cannot move to the given direction anymore by 5-way keys,
a list is scrolled with an animation to the other side and the spotlight focus moves in wraparound manner.
 * 
 * When it's  `'noAnimation'` , the spotlight focus moves in wraparound manner as same as when it's  `true` 
except that a list is scrolled without an animation.
 * 
 * Valid values are:
 * *  `false` ,
 * *  `true` , and
 * *  `'noAnimation'`
 */
  wrap?: boolean | "noAnimation";
}
/**
 * An Agate-styled scrollable and spottable virtual list component.
 */

export class VirtualList extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, VirtualListProps>
> {}

export interface VirtualGridListProps
  extends ui_VirtualList_VirtualListBasicProps {
  /**
 * Size of an item for the VirtualGridList; valid value is an object that has  `minWidth` 
and  `minHeight`  as properties.
 * 
 * Usage:
 * ```
<VirtualGridList
  itemSize={{
    minWidth: ri.scale(360),
    minHeight: ri.scale(540)
  }}
/>
```
 */
  itemSize: ui_VirtualList_gridListItemSizeShape;
  /**
 * A callback function that receives a reference to the  `scrollTo`  feature.
 * 
 * Once received, the  `scrollTo`  method can be called as an imperative interface.
 * 
 * The  `scrollTo`  function accepts the following parameters:
 * *  {position: {x, y}} - Pixel value for x and/or y position
 * *  {align} - Where the scroll area should be aligned. Values are:
 `'left'` ,  `'right'` ,  `'top'` ,  `'bottom'` ,
 `'topleft'` ,  `'topright'` ,  `'bottomleft'` , and  `'bottomright'` .
 * *  {index} - Index of specific item. ( `0`  or positive integer)
This option is available for only  `VirtualList`  kind.
 * *  {node} - Node to scroll into view
 * *  {animate} - When  `true` , scroll occurs with animation. When  `false` , no
animation occurs.
 * *  {focus} - When  `true` , attempts to focus item after scroll. Only valid when scrolling
  by  `index`  or  `node` .
 * 
 * Note: Only specify one of:  `position` ,  `align` ,  `index`  or  `node`
 * 
 * Example:
 * ```
// If you set cbScrollTo prop like below;
cbScrollTo: (fn) => {this.scrollTo = fn;}
// You can simply call like below;
this.scrollTo({align: 'top'}); // scroll to the top
```
 */
  cbScrollTo?: Function;
  /**
   * The layout direction of the list.
   */
  direction?: "horizontal" | "vertical";
  /**
 * Allows 5-way navigation to the scrollbar controls. By default, 5-way will
not move focus to the scrollbar controls.
 */
  focusableScrollbar?: boolean;
  /**
   * Specifies how to show horizontal scrollbar.
   */
  horizontalScrollbar?: "auto" | "visible" | "hidden";
  /**
 * Unique identifier for the component.
 * 
 * When defined and when the  `VirtualGridList`  is within a  Panel  ,
the  `VirtualGridList`  will store its scroll position and restore that position when returning to
the  `Panel` .
 */
  id?: string;
  /**
 * Called when scrolling.
 * 
 * Passes  `scrollLeft` ,  `scrollTop` , and  `moreInfo` .
It is not recommended to set this prop since it can cause performance degradation.
Use  `onScrollStart`  or  `onScrollStop`  instead.
 */
  onScroll?: Function;
  /**
 * Called when scroll starts.
 * 
 * Passes  `scrollLeft` ,  `scrollTop` , and  `moreInfo` .
You can get firstVisibleIndex and lastVisibleIndex from VirtualGridList with  `moreInfo` .
 * 
 * Example:
 * ```
onScrollStart = ({scrollLeft, scrollTop, moreInfo}) => {
    const {firstVisibleIndex, lastVisibleIndex} = moreInfo;
    // do something with firstVisibleIndex and lastVisibleIndex
}

render = () => (
    <VirtualGridList
        ...
        onScrollStart={this.onScrollStart}
        ...
    />
)
```
 */
  onScrollStart?: Function;
  /**
 * Called when scroll stops.
 * 
 * Passes  `scrollLeft` ,  `scrollTop` , and  `moreInfo` .
You can get firstVisibleIndex and lastVisibleIndex from VirtualGridList with  `moreInfo` .
 * 
 * Example:
 * ```
onScrollStop = ({scrollLeft, scrollTop, moreInfo}) => {
    const {firstVisibleIndex, lastVisibleIndex} = moreInfo;
    // do something with firstVisibleIndex and lastVisibleIndex
}

render = () => (
    <VirtualGridList
        ...
        onScrollStop={this.onScrollStop}
        ...
    />
)
```
 */
  onScrollStop?: Function;
  /**
   * The ARIA role for the list.
   */
  role?: string;
  /**
   * Sets the hint string read when focusing the next button in the vertical scroll bar.
   */
  scrollDownAriaLabel?: string;
  /**
   * Sets the hint string read when focusing the previous button in the horizontal scroll bar.
   */
  scrollLeftAriaLabel?: string;
  /**
   * Specifies how to scroll.
   *
   * Valid values are:
   * *  `'translate'` ,
   * *  `'native'` .
   */
  scrollMode?: string;
  /**
   * Sets the hint string read when focusing the next button in the horizontal scroll bar.
   */
  scrollRightAriaLabel?: string;
  /**
   * Sets the hint string read when focusing the previous button in the vertical scroll bar.
   */
  scrollUpAriaLabel?: string;
  /**
   * Specifies how to show vertical scrollbar.
   *
   * Valid values are:
   * *  `'auto'` ,
   * *  `'visible'` , and
   * *  `'hidden'` .
   */
  verticalScrollbar?: "auto" | "visible" | "hidden";
  /**
 * When it's  `true`  and the spotlight focus cannot move to the given direction anymore by 5-way keys,
a list is scrolled with an animation to the other side and the spotlight focus moves in wraparound manner.
 * 
 * When it's  `'noAnimation'` , the spotlight focus moves in wraparound manner as same as when it's  `true` 
except that a list is scrolled without an animation.
 * 
 * Valid values are:
 * *  `false` ,
 * *  `true` , and
 * *  `'noAnimation'`
 */
  wrap?: boolean | "noAnimation";
}
/**
 * An Agate-styled scrollable and spottable virtual grid list component.
 */

export class VirtualGridList extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, VirtualGridListProps>
> {}

export default VirtualList;
