import PropTypes from 'prop-types' ; import { Instance , GtkNode , Prop , Props } from '../types' ; export interface ElementConstructor { new ( node , props ? , meta ? ) : Element ; propTypes : object ; defaultProps : Props ; } interface Meta { isContainer ? : boolean ; mapChildren ? : string ; } export default class Element implements Instance { static defaultProps : Props = { } ; static propTypes : object = { } ; node : GtkNode ; props : Props ; isContainer : boolean ; mapChildren ? : string ; children : Element [ ] = [ ] ; constructor ( node , props = { } , meta = { } ) { const { isContainer = false , mapChildren } = meta ; this . node = node ; this . isContainer = isContainer ; this . mapChildren = mapChildren ; this . props = this . getProps ( props ) ; } appendChild ( child ) { this . update ( ) ; this . children . push ( child ) ; if ( this . isContainer ) this . node . add ( child . node ) ; } removeChild ( child ) { this . children . splice ( this . children . indexOf ( child ) , 1 ) ; if ( this . isContainer ) this . node . remove ( child . node ) ; } commitMount ( ) { this . update ( ) ; } commitUpdate ( newProps ) { this . props = { ... this . props , ... newProps } ; this . update ( ) ; } update ( ) { this . updateNode ( ) ; this . node . showAll ( ) ; } updateNode ( ) { if ( this . mapChildren && typeof this . props . children !== 'undefined' && this . props . children !== null ) { this . node [ this . mapChildren ] = this . props . children ; } Object . keys ( this . props ) . forEach ( ( key ) => { const prop = this . props [ key ] ; if ( typeof prop !== 'undefined' && prop !== null ) { this . node [ key ] = prop ; } } ) ; } getProps ( props ) { props = { ... props } ; const { defaultProps , propTypes } = this . constructor as ElementConstructor ; Object . keys ( defaultProps ) . forEach ( key => { const defaultProp = defaultProps [ key ] ; if ( typeof props [ key ] === 'undefined' || props [ key ] === null ) { props [ key ] = defaultProp ; } } ) ; PropTypes . checkPropTypes ( propTypes , props , 'prop' , this . constructor . name ) ; return props ; } }