/**
 * DO NOT EDIT
 *
 * This file was automatically generated by
 *   https://github.com/Polymer/gen-typescript-declarations
 *
 * To modify these typings, edit the source file(s):
 *   lib/elements/dom-repeat.html
 */

/// <reference path="../../polymer-element.d.ts" />
/// <reference path="../utils/templatize.d.ts" />
/// <reference path="../utils/debounce.d.ts" />
/// <reference path="../utils/flush.d.ts" />
/// <reference path="../mixins/mutable-data.d.ts" />

declare namespace Polymer {

  /**
   * The `<dom-repeat>` element will automatically stamp and binds one instance
   * of template content to each object in a user-provided array.
   * `dom-repeat` accepts an `items` property, and one instance of the template
   * is stamped for each item into the DOM at the location of the `dom-repeat`
   * element.  The `item` property will be set on each instance's binding
   * scope, thus templates should bind to sub-properties of `item`.
   *
   * Example:
   *
   * ```html
   * <dom-module id="employee-list">
   *
   *   <template>
   *
   *     <div> Employee list: </div>
   *     <dom-repeat items="{{employees}}">
   *       <template>
   *         <div>First name: <span>{{item.first}}</span></div>
   *         <div>Last name: <span>{{item.last}}</span></div>
   *       </template>
   *     </dom-repeat>
   *
   *   </template>
   *
   * </dom-module>
   * ```
   *
   * With the following custom element definition:
   *
   * ```js
   * class EmployeeList extends Polymer.Element {
   *   static get is() { return 'employee-list'; }
   *   static get properties() {
   *     return {
   *       employees: {
   *         value() {
   *           return [
   *             {first: 'Bob', last: 'Smith'},
   *             {first: 'Sally', last: 'Johnson'},
   *             ...
   *           ];
   *         }
   *       }
   *     };
   *   }
   * }
   * ```
   *
   * Notifications for changes to items sub-properties will be forwarded to template
   * instances, which will update via the normal structured data notification system.
   *
   * Mutations to the `items` array itself should be made using the Array
   * mutation API's on `Polymer.Base` (`push`, `pop`, `splice`, `shift`,
   * `unshift`), and template instances will be kept in sync with the data in the
   * array.
   *
   * Events caught by event handlers within the `dom-repeat` template will be
   * decorated with a `model` property, which represents the binding scope for
   * each template instance.  The model is an instance of Polymer.Base, and should
   * be used to manipulate data on the instance, for example
   * `event.model.set('item.checked', true);`.
   *
   * Alternatively, the model for a template instance for an element stamped by
   * a `dom-repeat` can be obtained using the `modelForElement` API on the
   * `dom-repeat` that stamped it, for example
   * `this.$.domRepeat.modelForElement(event.target).set('item.checked', true);`.
   * This may be useful for manipulating instance data of event targets obtained
   * by event handlers on parents of the `dom-repeat` (event delegation).
   *
   * A view-specific filter/sort may be applied to each `dom-repeat` by supplying a
   * `filter` and/or `sort` property.  This may be a string that names a function on
   * the host, or a function may be assigned to the property directly.  The functions
   * should implemented following the standard `Array` filter/sort API.
   *
   * In order to re-run the filter or sort functions based on changes to sub-fields
   * of `items`, the `observe` property may be set as a space-separated list of
   * `item` sub-fields that should cause a re-filter/sort when modified.  If
   * the filter or sort function depends on properties not contained in `items`,
   * the user should observe changes to those properties and call `render` to update
   * the view based on the dependency change.
   *
   * For example, for an `dom-repeat` with a filter of the following:
   *
   * ```js
   * isEngineer(item) {
   *   return item.type == 'engineer' || item.manager.type == 'engineer';
   * }
   * ```
   *
   * Then the `observe` property should be configured as follows:
   *
   * ```html
   * <dom-repeat items="{{employees}}" filter="isEngineer" observe="type manager.type">
   * ```
   */
  class DomRepeat extends
    Polymer.OptionalMutableData(
    Polymer.Element) {

    /**
     * An array containing items determining how many instances of the template
     * to stamp and that that each template instance should bind to.
     */
    items: any[]|null|undefined;

    /**
     * The name of the variable to add to the binding scope for the array
     * element associated with a given template instance.
     */
    as: string|null|undefined;

    /**
     * The name of the variable to add to the binding scope with the index
     * of the instance in the sorted and filtered list of rendered items.
     * Note, for the index in the `this.items` array, use the value of the
     * `itemsIndexAs` property.
     */
    indexAs: string|null|undefined;

    /**
     * The name of the variable to add to the binding scope with the index
     * of the instance in the `this.items` array. Note, for the index of
     * this instance in the sorted and filtered list of rendered items,
     * use the value of the `indexAs` property.
     */
    itemsIndexAs: string|null|undefined;

    /**
     * A function that should determine the sort order of the items.  This
     * property should either be provided as a string, indicating a method
     * name on the element's host, or else be an actual function.  The
     * function should match the sort function passed to `Array.sort`.
     * Using a sort function has no effect on the underlying `items` array.
     */
    sort: Function|null|undefined;

    /**
     * A function that can be used to filter items out of the view.  This
     * property should either be provided as a string, indicating a method
     * name on the element's host, or else be an actual function.  The
     * function should match the sort function passed to `Array.filter`.
     * Using a filter function has no effect on the underlying `items` array.
     */
    filter: Function|null|undefined;

    /**
     * When using a `filter` or `sort` function, the `observe` property
     * should be set to a space-separated list of the names of item
     * sub-fields that should trigger a re-sort or re-filter when changed.
     * These should generally be fields of `item` that the sort or filter
     * function depends on.
     */
    observe: string|null|undefined;

    /**
     * When using a `filter` or `sort` function, the `delay` property
     * determines a debounce time in ms after a change to observed item
     * properties that must pass before the filter or sort is re-run.
     * This is useful in rate-limiting shuffling of the view when
     * item changes may be frequent.
     */
    delay: number|null|undefined;

    /**
     * Count of currently rendered items after `filter` (if any) has been applied.
     * If "chunking mode" is enabled, `renderedItemCount` is updated each time a
     * set of template instances is rendered.
     */
    readonly renderedItemCount: number|null|undefined;

    /**
     * Defines an initial count of template instances to render after setting
     * the `items` array, before the next paint, and puts the `dom-repeat`
     * into "chunking mode".  The remaining items will be created and rendered
     * incrementally at each animation frame therof until all instances have
     * been rendered.
     */
    initialCount: number|null|undefined;

    /**
     * When `initialCount` is used, this property defines a frame rate (in
     * fps) to target by throttling the number of instances rendered each
     * frame to not exceed the budget for the target frame rate.  The
     * framerate is effectively the number of `requestAnimationFrame`s that
     * it tries to allow to actually fire in a given second. It does this
     * by measuring the time between `rAF`s and continuously adjusting the
     * number of items created each `rAF` to maintain the target framerate.
     * Setting this to a higher number allows lower latency and higher
     * throughput for event handlers and other tasks, but results in a
     * longer time for the remaining items to complete rendering.
     */
    targetFramerate: number|null|undefined;
    readonly _targetFrameTime: number|null|undefined;
    connectedCallback(): void;
    disconnectedCallback(): void;

    /**
     * Forces the element to render its content. Normally rendering is
     * asynchronous to a provoking change. This is done for efficiency so
     * that multiple changes trigger only a single render. The render method
     * should be called if, for example, template rendering is required to
     * validate application state.
     */
    render(): void;

    /**
     * Shows or hides the template instance top level child elements. For
     * text nodes, `textContent` is removed while "hidden" and replaced when
     * "shown."
     *
     * @param hidden Set to true to hide the children;
     * set to false to show them.
     */
    _showHideChildren(hidden: boolean): void;

    /**
     * Returns the item associated with a given element stamped by
     * this `dom-repeat`.
     *
     * Note, to modify sub-properties of the item,
     * `modelForElement(el).set('item.<sub-prop>', value)`
     * should be used.
     *
     * @param el Element for which to return the item.
     * @returns Item associated with the element.
     */
    itemForElement(el: HTMLElement): any;

    /**
     * Returns the inst index for a given element stamped by this `dom-repeat`.
     * If `sort` is provided, the index will reflect the sorted order (rather
     * than the original array order).
     *
     * @param el Element for which to return the index.
     * @returns Row index associated with the element (note this may
     *   not correspond to the array index if a user `sort` is applied).
     */
    indexForElement(el: HTMLElement): number|null;

    /**
     * Returns the template "model" associated with a given element, which
     * serves as the binding scope for the template instance the element is
     * contained in. A template model is an instance of `Polymer.Base`, and
     * should be used to manipulate data associated with this template instance.
     *
     * Example:
     *
     *   let model = modelForElement(el);
     *   if (model.index < 10) {
     *     model.set('item.checked', true);
     *   }
     *
     * @param el Element for which to return a template model.
     * @returns Model representing the binding scope for
     *   the element.
     */
    modelForElement(el: HTMLElement): TemplateInstanceBase|null;
  }
}

interface HTMLElementTagNameMap {
  "dom-repeat": Polymer.DomRepeat;
}
