// Type definitions for sandstone/Scroller

import { ScrollerBasicProps as ui_Scroller_ScrollerBasicProps } from "@enact/ui/Scroller";
import * as React from "react";

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 ContentContainerDecoratorProps {}
export function ContentContainerDecorator<P>(
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & ContentContainerDecoratorProps>;

/**
 * The shape for editable of   .
 */
export interface EditableShape {
  /**
 * The callback function called when editing is finished.
It has an event object contains  `orders`  array which app can use for repopulate items.
 */
  onComplete: Function /**
 * Obtains a reference to  `blurItem`  function.
If you would like to remove  `focused`  CSS class to an item, you can get the reference to  `blurItem`  function via  `useRef` .
 `blurItem`  function needs to be called with an item node when an item is blurred.
 */;
  blurItemFuncRef?: Function | object /**
   * Centers the contents of the scroller.
   */;
  centered?: boolean /**
 * Customizes the component by mapping the supplied collection of CSS class names to the
corresponding internal elements and states of this component.
The following classes are supported:
 * *  `wrapper`  - The content wrapper component class
 * *  `selected`  - The selected item class
 * *  `focused`  - The focused item class
 */;
  css?: object /**
 * Obtains a reference to  `focusItem`  function.
If you would like to use  `focused`  CSS class to an item, you can get the reference to  `focusItem`  function via  `useRef` .
 `focusItem`  function needs to be called with an item node when an item is focused.
 */;
  focusItemFuncRef?: Function | object /**
 * Obtains a reference to  `hideItem`  function.
If you would like to hide an item, you can get the reference to  `hideItem`  function via  `useRef` .
 */;
  hideItemFuncRef?: Function | object /**
 * Obtains a reference to  `removeItem`  function.
If you would like to remove an item, you can get the reference to  `removeItem`  function via  `useRef` .
 */;
  removeItemFuncRef?: Function | object /**
 * Decides how to start editing items.
It can be either  `'press'`  or  `'longPress'` . If unset, it defaults to  `'longPress'` .
 */;
  selectItemBy?: string /**
 * Obtains a reference to  `showItem`  function.
If you would like to show an item, you can get the reference to  `showItem`  function via  `useRef` .
 */;
  showItemFuncRef?: Function | object;
}
export interface ScrollerProps extends ui_Scroller_ScrollerBasicProps {
  /**
 * The "aria-label" for the Scroller.
 * 
 * When  `aria-label`  is set and  `focusableScrollbar`  is  `byEnter` , it will be used
instead to provide an accessibility label for the Scroller.
 */
  "aria-label"?: string;
  /**
 * A callback function that receives a reference to the  `scrollTo`  feature.
 * 
 * Once received, the  `scrollTo`  method can be called as an imperative interface.
 * *  {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'` .
 * *  {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  `node` .
 * 
 * Note: Only specify one of:  `position` ,  `align` ,  `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;
  /**
   * Disable voice control feature of component.
   */
  "data-webos-voice-disabled"?: boolean;
  /**
   * Activates the component for voice control.
   */
  "data-webos-voice-focused"?: boolean;
  /**
   * The voice control group label.
   */
  "data-webos-voice-group-label"?: string;
  /**
   * Direction of the scroller.
   */
  direction?: "both" | "horizontal" | "vertical";
  /**
 * Enables editing items in the scroller.
You can specify props for editable scroller as an object.
See the details in  
 */
  editable?: EditableShape;
  /**
   * Adds fade-out effect on the scroller.
   *
   * Set this to  `true`  only if the content has no spottable but text.
   *
   * Note: Fade-out effect will not show if the  `direction`  is set to  `both` .
   */
  fadeOut?: boolean;
  /**
 * Allows 5-way navigation to the scroll thumb.
 * 
 * By default, 5-way will not move focus to the scroll thumb.
If  `true` , the scroll thumb will get focus by directional keys.
If  `'byEnter'` , scroll thumb will get focus first by directional keys,
then the scroll body will get focus by enter key or back key pressed on scroll thumb.
 */
  focusableScrollbar?: boolean | "byEnter";
  /**
   * Specifies how to show horizontal scrollbar.
   */
  horizontalScrollbar?: "auto" | "visible" | "hidden";
  /**
   * Sets the hint string read when focusing the scroll thumb in the horizontal scroll bar.
   */
  horizontalScrollThumbAriaLabel?: string;
  /**
   * Enables scroll by hover on edges in scroll direction.
   */
  hoverToScroll?: boolean;
  /**
 * Unique identifier for the component.
 * 
 * When defined and when the  `Scroller`  is within a   , the
 `Scroller`  will store its scroll position and restore that position when returning to the
 `Panel` .
 */
  id?: string;
  /**
   * Prevents scroll by wheeling on the scroller.
   */
  noScrollByWheel?: boolean;
  /**
 * Called when scrolling.
 * 
 * Passes  `scrollLeft` ,  `scrollTop` .
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`  and  `scrollTop` .
 * 
 * Example:
 * ```
onScrollStart = ({scrollLeft, scrollTop}) => {
    // do something with scrollLeft and scrollTop
}

render = () => (
    <Scroller
        ...
        onScrollStart={this.onScrollStart}
        ...
    />
)
```
 */
  onScrollStart?: Function;
  /**
 * Called when scroll stops.
 * 
 * Passes  `scrollLeft`  and  `scrollTop` .
 * 
 * Example:
 * ```
onScrollStop = ({scrollLeft, scrollTop}) => {
    // do something with scrollLeft and scrollTop
}

render = () => (
    <Scroller
        ...
        onScrollStop={this.onScrollStop}
        ...
    />
)
```
 */
  onScrollStop?: Function;
  /**
 * Customizes the component by mapping the supplied collection of CSS class names to the
corresponding internal elements and states of this component.
 * 
 * The following classes are supported:
 * *  `scrollbarTrack`  - The scrollbarTrack component class
 * *  `thumb`  - The scrollbar thumb component class
 */
  scrollbarTrackCss?: object;
  /**
   * Specifies how to scroll.
   */
  scrollMode?: "native" | "translate";
  /**
   * Specifies how to show vertical scrollbar.
   */
  verticalScrollbar?: "auto" | "visible" | "hidden";
  /**
   * Sets the hint string read when focusing the scroll thumb in the vertical scroll bar.
   */
  verticalScrollThumbAriaLabel?: string;
}
/**
 * A Sandstone-styled Scroller, useScroll applied.
 * 
 * Usage:
 * ```
<Scroller>Scroll me.</Scroller>
```
 */

export class Scroller extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, ScrollerProps>
> {}

export interface EditableWrapperProps {
  /**
 * Enables editing items in the scroller.
You can specify props for editable scroller as an object.
See the datails in  
 */
  editable?: EditableShape;
  /**
   * Obtains a reference to the scroll container handle.
   */
  scrollContainerHandle?: Function | object;
  /**
   * Obtains a reference to the scroll container node.
   */
  scrollContainerRef?: Function | object;
  /**
   * Obtains a reference to the scroll content node.
   */
  scrollContentRef?: Function | object;
}
/**
 * A Sandstone-styled EditableWrapper.
 */

export class EditableWrapper extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, EditableWrapperProps>
> {}

export default Scroller;
