/**
 * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module ui/view
 */
import ViewCollection from './viewcollection.js';
import Template, { type BindChain, type TemplateDefinition } from './template.js';
import { Collection, type DecoratedMethodEvent, type Locale, type LocaleTranslate } from '@ckeditor/ckeditor5-utils';
import '../theme/globals/globals.css';
declare const View_base: import("@ckeditor/ckeditor5-utils").Mixed<{
    new (): import("@ckeditor/ckeditor5-utils").Observable;
    prototype: import("@ckeditor/ckeditor5-utils").Observable;
}, import("@ckeditor/ckeditor5-utils").DomEmitter>;
/**
 * The basic view class, which represents an HTML element created out of a
 * {@link module:ui/view~View#template}. Views are building blocks of the user interface and handle
 * interaction
 *
 * Views {@link module:ui/view~View#registerChild aggregate} children in
 * {@link module:ui/view~View#createCollection collections} and manage the life cycle of DOM
 * listeners e.g. by handling rendering and destruction.
 *
 * See the {@link module:ui/template~TemplateDefinition} syntax to learn more about shaping view
 * elements, attributes and listeners.
 *
 * ```ts
 * class SampleView extends View {
 * 	constructor( locale ) {
 * 		super( locale );
 *
 * 		const bind = this.bindTemplate;
 *
 * 		// Views define their interface (state) using observable attributes.
 * 		this.set( 'elementClass', 'bar' );
 *
 * 		this.setTemplate( {
 * 			tag: 'p',
 *
 * 			// The element of the view can be defined with its children.
 * 			children: [
 * 				'Hello',
 * 				{
 * 					tag: 'b',
 * 					children: [ 'world!' ]
 * 				}
 * 			],
 * 			attributes: {
 * 				class: [
 * 					'foo',
 *
 * 					// Observable attributes control the state of the view in DOM.
 * 					bind.to( 'elementClass' )
 * 				]
 * 			},
 * 			on: {
 * 				// Views listen to DOM events and propagate them.
 * 				click: bind.to( 'clicked' )
 * 			}
 * 		} );
 * 	}
 * }
 *
 * const view = new SampleView( locale );
 *
 * view.render();
 *
 * // Append <p class="foo bar">Hello<b>world</b></p> to the <body>
 * document.body.appendChild( view.element );
 *
 * // Change the class attribute to <p class="foo baz">Hello<b>world</b></p>
 * view.elementClass = 'baz';
 *
 * // Respond to the "click" event in DOM by executing a custom action.
 * view.on( 'clicked', () => {
 * 	console.log( 'The view has been clicked!' );
 * } );
 * ```
 */
export default class View<TElement extends HTMLElement = HTMLElement> extends View_base {
    /**
     * An HTML element of the view. `null` until {@link #render rendered}
     * from the {@link #template}.
     *
     * ```ts
     * class SampleView extends View {
     * 	constructor() {
     * 		super();
     *
     * 		// A template instance the #element will be created from.
     * 		this.setTemplate( {
     * 			tag: 'p'
     *
     * 			// ...
     * 		} );
     * 	}
     * }
     *
     * const view = new SampleView();
     *
     * // Renders the #template.
     * view.render();
     *
     * // Append the HTML element of the view to <body>.
     * document.body.appendChild( view.element );
     * ```
     *
     * **Note**: The element of the view can also be assigned directly:
     *
     * ```ts
     * view.element = document.querySelector( '#my-container' );
     * ```
     */
    element: TElement | null;
    /**
     * Set `true` when the view has already been {@link module:ui/view~View#render rendered}.
     *
     * @readonly
     */
    isRendered: boolean;
    /**
     * A set of tools to localize the user interface.
     *
     * Also see {@link module:core/editor/editor~Editor#locale}.
     *
     * @readonly
     */
    locale: Locale | undefined;
    /**
     * Shorthand for {@link module:utils/locale~Locale#t}.
     *
     * Note: If {@link #locale} instance hasn't been passed to the view this method may not
     * be available.
     *
     * @see module:utils/locale~Locale#t
     */
    t: LocaleTranslate | undefined;
    /**
     * Template of this view. It provides the {@link #element} representing
     * the view in DOM, which is {@link #render rendered}.
     */
    template?: Template;
    viewUid?: string;
    /**
     * Collections registered with {@link #createCollection}.
     */
    protected _viewCollections: Collection<ViewCollection>;
    /**
     * A collection of view instances, which have been added directly
     * into the {@link module:ui/template~Template#children}.
     */
    protected _unboundChildren: ViewCollection;
    /**
     * Cached {@link module:ui/template~BindChain bind chain} object created by the
     * {@link #template}. See {@link #bindTemplate}.
     */
    private _bindTemplate?;
    /**
     * Creates an instance of the {@link module:ui/view~View} class.
     *
     * Also see {@link #render}.
     *
     * @param locale The localization services instance.
     */
    constructor(locale?: Locale);
    /**
     * Shorthand for {@link module:ui/template~Template.bind}, a binding
     * {@link module:ui/template~BindChain interface} pre–configured for the view instance.
     *
     * It provides {@link module:ui/template~BindChain#to `to()`} and
     * {@link module:ui/template~BindChain#if `if()`} methods that initialize bindings with
     * observable attributes and attach DOM listeners.
     *
     * ```ts
     * class SampleView extends View {
     * 	constructor( locale ) {
     * 		super( locale );
     *
     * 		const bind = this.bindTemplate;
     *
     * 		// These {@link module:utils/observablemixin~Observable observable} attributes will control
     * 		// the state of the view in DOM.
     * 		this.set( {
     * 			elementClass: 'foo',
     * 		 	isEnabled: true
     * 		 } );
     *
     * 		this.setTemplate( {
     * 			tag: 'p',
     *
     * 			attributes: {
     * 				// The class HTML attribute will follow elementClass
     * 				// and isEnabled view attributes.
     * 				class: [
     * 					bind.to( 'elementClass' )
     * 					bind.if( 'isEnabled', 'present-when-enabled' )
     * 				]
     * 			},
     *
     * 			on: {
     * 				// The view will fire the "clicked" event upon clicking <p> in DOM.
     * 				click: bind.to( 'clicked' )
     * 			}
     * 		} );
     * 	}
     * }
     * ```
     */
    get bindTemplate(): BindChain<this>;
    /**
     * Creates a new collection of views, which can be used as
     * {@link module:ui/template~Template#children} of this view.
     *
     * ```ts
     * class SampleView extends View {
     * 	constructor( locale ) {
     * 		super( locale );
     *
     * 		const child = new ChildView( locale );
     * 		this.items = this.createCollection( [ child ] );
     *
     * 		this.setTemplate( {
     * 			tag: 'p',
     *
     * 			// `items` collection will render here.
     * 			children: this.items
     * 		} );
     * 	}
     * }
     *
     * const view = new SampleView( locale );
     * view.render();
     *
     * // It will append <p><child#element></p> to the <body>.
     * document.body.appendChild( view.element );
     * ```
     *
     * @param views Initial views of the collection.
     * @returns A new collection of view instances.
     */
    createCollection<T extends View = View>(views?: Iterable<T>): ViewCollection<T>;
    /**
     * Registers a new child view under the view instance. Once registered, a child
     * view is managed by its parent, including {@link #render rendering}
     * and {@link #destroy destruction}.
     *
     * To revert this, use {@link #deregisterChild}.
     *
     * ```ts
     * class SampleView extends View {
     * 	constructor( locale ) {
     * 		super( locale );
     *
     * 		this.childA = new SomeChildView( locale );
     * 		this.childB = new SomeChildView( locale );
     *
     * 		this.setTemplate( { tag: 'p' } );
     *
     * 		// Register the children.
     * 		this.registerChild( [ this.childA, this.childB ] );
     * 	}
     *
     * 	render() {
     * 		super.render();
     *
     * 		this.element.appendChild( this.childA.element );
     * 		this.element.appendChild( this.childB.element );
     * 	}
     * }
     *
     * const view = new SampleView( locale );
     *
     * view.render();
     *
     * // Will append <p><childA#element><b></b><childB#element></p>.
     * document.body.appendChild( view.element );
     * ```
     *
     * **Note**: There's no need to add child views if they're already referenced in the
     * {@link #template}:
     *
     * ```ts
     * class SampleView extends View {
     * 	constructor( locale ) {
     * 		super( locale );
     *
     * 		this.childA = new SomeChildView( locale );
     * 		this.childB = new SomeChildView( locale );
     *
     * 		this.setTemplate( {
     * 			tag: 'p',
     *
     * 			// These children will be added automatically. There's no
     * 			// need to call {@link #registerChild} for any of them.
     * 			children: [ this.childA, this.childB ]
     * 		} );
     * 	}
     *
     * 	// ...
     * }
     * ```
     *
     * @param children Children views to be registered.
     */
    registerChild(children: View | Iterable<View>): void;
    /**
     * The opposite of {@link #registerChild}. Removes a child view from this view instance.
     * Once removed, the child is no longer managed by its parent, e.g. it can safely
     * become a child of another parent view.
     *
     * @see #registerChild
     * @param children Child views to be removed.
     */
    deregisterChild(children: View | Iterable<View>): void;
    /**
     * Sets the {@link #template} of the view with with given definition.
     *
     * A shorthand for:
     *
     * ```ts
     * view.setTemplate( definition );
     * ```
     *
     * @param definition Definition of view's template.
     */
    setTemplate(definition: TemplateDefinition): void;
    /**
     * {@link module:ui/template~Template.extend Extends} the {@link #template} of the view with
     * with given definition.
     *
     * A shorthand for:
     *
     * ```ts
     * Template.extend( view.template, definition );
     * ```
     *
     * **Note**: Is requires the {@link #template} to be already set. See {@link #setTemplate}.
     *
     * @param definition Definition which extends the {@link #template}.
     */
    extendTemplate(definition: Partial<TemplateDefinition>): void;
    /**
     * Recursively renders the view.
     *
     * Once the view is rendered:
     * * the {@link #element} becomes an HTML element out of {@link #template},
     * * the {@link #isRendered} flag is set `true`.
     *
     * **Note**: The children of the view:
     * * defined directly in the {@link #template}
     * * residing in collections created by the {@link #createCollection} method,
     * * and added by {@link #registerChild}
     * are also rendered in the process.
     *
     * In general, `render()` method is the right place to keep the code which refers to the
     * {@link #element} and should be executed at the very beginning of the view's life cycle.
     *
     * It is possible to {@link module:ui/template~Template.extend} the {@link #template} before
     * the view is rendered. To allow an early customization of the view (e.g. by its parent),
     * such references should be done in `render()`.
     *
     * ```ts
     * class SampleView extends View {
     * 	constructor() {
     * 		this.setTemplate( {
     * 			// ...
     * 		} );
     * 	},
     *
     * 	render() {
     * 		// View#element becomes available.
     * 		super.render();
     *
     * 		// The "scroll" listener depends on #element.
     * 		this.listenTo( window, 'scroll', () => {
     * 			// A reference to #element would render the #template and make it non-extendable.
     * 			if ( window.scrollY > 0 ) {
     * 				this.element.scrollLeft = 100;
     * 			} else {
     * 				this.element.scrollLeft = 0;
     * 			}
     * 		} );
     * 	}
     * }
     *
     * const view = new SampleView();
     *
     * // Let's customize the view before it gets rendered.
     * view.extendTemplate( {
     * 	attributes: {
     * 		class: [
     * 			'additional-class'
     * 		]
     * 	}
     * } );
     *
     * // Late rendering allows customization of the view.
     * view.render();
     * ```
     */
    render(): void;
    /**
     * Recursively destroys the view instance and child views added by {@link #registerChild} and
     * residing in collections created by the {@link #createCollection}.
     *
     * Destruction disables all event listeners:
     * * created on the view, e.g. `view.on( 'event', () => {} )`,
     * * defined in the {@link #template} for DOM events.
     */
    destroy(): void;
}
/**
 * Event fired by the {@link module:ui/view~View#render} method. Actual rendering is executed as a listener to
 * this event with the default priority.
 *
 * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.
 *
 * @eventName ~View#render
 */
export type UIViewRenderEvent = DecoratedMethodEvent<View, 'render'>;
export {};
