import * as React from "react" ; import * as ReactDOM from "react-dom" ; import { Map , OrderedSet , Set , } from "immutable" ; import * as PropTypes from "prop-types" ; import { ClassNameMetaBase , DefaultComponentBase , } from "@react-mdc/base" ; import { FoundationAdapter , InputAdapter } from "./adapter" ; import { BASE_CLASS_NAME } from "./constants" ; export const CLASS_NAME = `${ BASE_CLASS_NAME }__input` ; export type ChildProps = { className ? : string ; } ; export type MetaProps = { className ? : string ; } ; export type State = { foundationEventListeners : Map < string , Set < EventListener > > ; } ; export type Context = { adapter : FoundationAdapter ; } ; /**
 * Textfield input component
 */ export class Meta extends ClassNameMetaBase < ChildProps , MetaProps , State > { public static contextTypes = { adapter : PropTypes . instanceOf ( FoundationAdapter ) . isRequired , } ; public context : Context ; public state : State = { foundationEventListeners : Map < string , Set < EventListener > > ( ) , } ; public componentDidMount ( ) { this . context . adapter . setInputAdapter ( new InputAdapterImpl ( this ) ) ; } public componentWillUnmount ( ) { this . context . adapter . setInputAdapter ( new InputAdapter ( ) ) ; } protected renderNativeDOMProps ( ) { return { eventListeners : this . state . foundationEventListeners . toJS ( ) , } ; } protected renderBaseClassName ( ) { return CLASS_NAME ; } } class InputAdapterImpl extends InputAdapter { private element : Meta ; constructor ( element ) { super ( ) ; this . element = element ; } public registerInputFocusHandler ( handler ) { this . registerInputHandler ( "focus" , handler ) ; } public deregisterInputFocusHandler ( handler ) { this . deregisterInputHandler ( "focus" , handler ) ; } public registerInputBlurHandler ( handler ) { this . registerInputHandler ( "blur" , handler ) ; } public deregisterInputBlurHandler ( handler ) { this . deregisterInputHandler ( "blur" , handler ) ; } public registerInputInputHandler ( handler ) { this . registerInputHandler ( "input" , handler ) ; } public deregisterInputInputHandler ( handler ) { this . deregisterInputHandler ( "input" , handler ) ; } public registerInputKeydownHandler ( handler ) { this . registerInputHandler ( "keydown" , handler ) ; } public deregisterInputKeydownHandler ( handler ) { this . deregisterInputHandler ( "keydown" , handler ) ; } public getNativeInput ( ) { return ReactDOM . findDOMNode ( this . element ) as HTMLInputElement ; } private registerInputHandler ( evt , handler ) { this . element . setState ( ( state ) => ( { foundationEventListeners : state . foundationEventListeners . update ( evt , OrderedSet < EventListener > ( ) , ( x ) => x . add ( handler ) ) , } ) ) ; } private deregisterInputHandler ( evt , handler ) { this . element . setState ( ( state ) => ( { foundationEventListeners : state . foundationEventListeners . update ( evt , OrderedSet < EventListener > ( ) , ( x ) => x . delete ( handler ) ) , } ) ) ; } } function TextInput ( props ) { return ( < input type = "text" { ... props } />); } export default class Input extends DefaultComponentBase < React . HTMLProps < HTMLInputElement > , MetaProps , { } > { public static Meta = Meta ; protected getMetaComponent ( ) { return Meta ; } protected getMetaPropNames ( ) { return [ "className" , ] ; } protected getChildComponent ( ) { return TextInput ; } }