/**
 * Copyright (c) 2020 Dell Inc., or its subsidiaries. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */ import * as React from "react" ; import { UID } from "react-uid" ; import { classNames } from "../../utils" ; import { Icon } from "../../icon" ; import { ClassNames } from "./ClassNames" ; import { DebounceUtils } from "../common/DebounceUtils" ; /**
 * General component description :
 * DataList :
 * The datalist element offers a flexible input when users need to filter
 * and select from a large list of pre-defined options.
 * Or, they need to input a custom value
 * (not provided in the pre-defined list) for the input.
 */ param { value } option param { selected } true param { style } CSS param { className } CSS type DataListOptionProps = { value ? : any ; selected ? : boolean ; className ? : string ; style ? : any ; } ; export const DataListOption = ( { value , selected , children , className , style , } ) => { return ( < option value = { value } selected = { selected } className = { classNames ( [ ClassNames . NG_STAR_INSERTED , className ] ) } style = { style } > { children } < /option>); } ; /**
 * Enum for datalist autocomplete status
 */ export enum DataListAutoComplete { ON = "on" , OFF = "off" } param { placeHolder } placeHolder param { label } label param { name } name param { required } true param { isError } true param { errorTitle } error param { errorText } error param { helperText } helper param { onChange } function param { onBlur } function param { dataqa } quality param { style } CSS param { className } CSS param { autoComplete } if param { spellCheck } specifies param { defaultValue } if param { debounceTime } if param { value } if type DataListProps = { placeHolder ? : string ; label ? : string ; name ? : string ; title ? : string ; required ? : boolean ; isError ? : boolean ; errorText ? : string ; errorTitle ? : string ; helperText ? : string ; onChange ? : ( evt : React . ChangeEvent < HTMLInputElement > ) => void ; onBlur ? : ( evt : React . FocusEvent < HTMLInputElement > ) => void ; autoComplete ? : DataListAutoComplete ; dataqa ? : string ; className ? : string ; style ? : any ; defaultValue ? : any ; spellCheck ? : boolean ; debounce ? : boolean ; debounceTime ? : number ; value ? : any ; } ; param { hasFocus } true type DataListState = { hasFocus : boolean ; } ; export class DataList extends React . PureComponent < DataListProps , DataListState > { constructor ( props ) { super ( props ) ; this . state = { hasFocus : false , } ; } private handleFocus = ( evt ) => { this . setState ( { hasFocus : true } ) ; } ; private handleBlur = ( evt ) => { const { onBlur } = this . props ; this . setState ( { hasFocus : false } , ( ) => { onBlur && onBlur ( evt ) ; } ) ; } ; private renderHelperText ( helperText ) { return < span className = { classNames ( [ ClassNames . CLR_SUBTEXT , ClassNames . NG_STAR_INSERTED ] ) } > { helperText } < /span>; } private renderLabel ( labelString ) { return ( < label className = { classNames ( [ ClassNames . CLR_CONTROL_LABEL , ClassNames . DATALIST_LABEL_COL , ClassNames . NG_STAR_INSERTED , ] ) } > { labelString } < /label>); } private renderDataList ( ) { const debounceOnChange = new DebounceUtils ( ) ; const { placeHolder , name , title , errorTitle , isError , errorText , helperText , required , className , style , children , onChange , autoComplete , defaultValue , spellCheck , debounce , debounceTime , value , } = this . props ; const { hasFocus } = this . state ; return ( < div className = { ClassNames . CLR_INPUT_WRAPPER } > < UID > { listId => ( < div className = { classNames ( [ ClassNames . CLR_INPUT_GROUP , hasFocus && ClassNames . CLR_FOCUS , className , ] ) } style = { style } > < input onFocus = { this . handleFocus } onBlur = { this . handleBlur } onChange = { ( evt ) => debounceOnChange . debounce ( evt , onChange , debounce , debounceTime ) } placeholder = { placeHolder } name = { name } required = { required } list = { listId } style = { { width : "100%" } } className = { classNames ( [ ClassNames . CLR_INPUT , ClassNames . NG_VALID , ClassNames . NG_TOUCHED , ClassNames . NG_DIRTY , ] ) } aria - describedby = "clr-form-control-3-helper" type = "text" spellCheck = { spellCheck } autoComplete = { autoComplete ? autoComplete : DataListAutoComplete . OFF } value = { value } defaultValue = { defaultValue ? defaultValue : "" } title = { title } / > < datalist id = { listId } > { children } < /datalist> < /div>)} < /UID> < Icon className = { ClassNames . CLR_VALIDATE_ICON } shape = "exclamation-circle" title = { errorTitle } / > { isError ? errorText && this . renderHelperText ( errorText ) : helperText && this . renderHelperText ( helperText ) } < /div>); } render ( ) { const { label , isError , dataqa } = this . props ; return ( < div data - qa = { dataqa } className = { classNames ( [ ClassNames . NG_VALID , ClassNames . CLR_FORM , ClassNames . CLR_FORM_HORIZONTAL , ClassNames . NG_TOUCHED , ClassNames . NG_DIRTY , ] ) } > < div className = { classNames ( [ ClassNames . CLR_DATALIST_CONTAINER , ClassNames . CLR_FORM_CONTROL , ClassNames . CLR_ROW , ] ) } > { label && this . renderLabel ( label ) } < div className = { classNames ( [ ClassNames . CLR_CONTROL_CONTAINER , isError && ClassNames . CLR_ERROR , ClassNames . DATALIST_COL , ] ) } > { this . renderDataList ( ) } < /div> < /div> < /div>); } }