import React, { FunctionComponent, useEffect, useRef, useState } from 'react'
import {
View,
Text,
TextInput,
TouchableOpacity
} from 'react-native';
import Icon from '../icon'
import { IComponent, ComponentDefaults } from '../utils/typings'
import { useConfig } from '../configprovider';
import searchbarStyles from './styles';
type TIconDirection = 'in-left' | 'out-left' | 'in-right' | 'out-right'
export interface SearchBarProps extends IComponent {
/** 文本值 */
value?: number | string
/** 输入框占位提示文字 */
placeholder?: string
/** 搜索框形状,可选值为 round */
shape?: 'square' | 'round'
/** 是否禁用输入框 */
disabled?: boolean
/** 最大输入长度 */
maxLength?: number
/** 是否启用清除图标,点击清除图标后会清空输入框 */
clearable?: boolean
/** 搜索框外部背景色 */
background?: string
/** 搜索框背景色 */
inputBackground?: string
/** 输入框内容对齐方式 */
align?: string
/** 是否将输入框设为只读状态,只读状态下无法输入内容 */
readOnly?: boolean
/** 是否自动聚焦,iOS 系统不支持该属性 */
autoFocus?: boolean
/** 搜索框左侧文本 */
label?: React.ReactNode
/** 输入框内 左icon */
leftinIcon?: React.ReactNode
/** 输入框内 右icon */
rightinIcon?: React.ReactNode
/** 输入框外 左icon */
leftoutIcon?: React.ReactNode
/** 输入框外 右icon */
rightoutIcon?: React.ReactNode
/** 取消按钮文字 */
actionText?: React.ReactNode
/** 确定搜索时触发 */
onSearch?: (val: string) => void
/** 输入框内容变化时触发 */
onChange?: (value: string, event: Event) => void
/** 输入框获得焦点时触发 */
onFocus?: (value: string, event: Event) => void
/** 输入框失去焦点时触发 */
onBlur?: (value: string, event: Event) => void
/** 点击清除按钮后触发 */
onClear?: (event: Event) => void
/** 点击取消按钮后触发 */
onCancel?: () => void
/** 点击输入框内左侧图标时触发 */
onClickLeftinIcon?: (value: string, event: Event) => void
/** 点击输入框外左侧图标时触发 */
onClickLeftoutIcon?: (value: string, event: Event) => void
/** 点击输入框内右侧图标时触发 */
onClickRightinIcon?: (value: string, event: Event) => void
/** 点击输入框外右侧图标时触发 */
onClickRightoutIcon?: (value: string, event: Event) => void
}
const defaultProps = {
...ComponentDefaults,
placeholder: '',
shape: 'square',
disabled: false,
maxLength: 9999,
clearable: true,
align: 'left',
readonly: true,
autoFocus: false,
label: '',
leftinIcon: ,
} as SearchBarProps
export const SearchBar: FunctionComponent<
Partial &
Omit<
React.HTMLAttributes,
'onChange' | 'onFocus' | 'onBlur'
>
> = (props) => {
const { theme } = useConfig();
const mStyles = searchbarStyles(theme);
const searchRef = useRef(null)
const [value, setValue] = useState(() => props.value)
const {
placeholder,
shape,
disabled,
maxLength,
clearable,
align,
readOnly,
autoFocus,
label,
actionText,
leftinIcon,
rightinIcon,
leftoutIcon,
rightoutIcon,
onChange,
onFocus,
onBlur,
onClear,
onCancel,
onSearch,
onClickLeftinIcon,
onClickLeftoutIcon,
onClickRightinIcon,
onClickRightoutIcon,
iconClassPrefix,
iconFontClassName,
} = {
...defaultProps,
...props,
}
const alignClass = `${align}`
const change = (event: Event) => {
const { text } = event?.nativeEvent as any
onChange && onChange?.(text, event)
setValue(text)
}
const focus = (event: Event) => {
const { text } = event?.nativeEvent as any
onFocus && onFocus?.(text, event)
}
const blur = (event: Event) => {
const searchSelf: HTMLInputElement | null = searchRef.current
searchSelf && searchSelf.blur()
const { text } = event?.nativeEvent as any
onBlur && onBlur?.(text, event)
}
useEffect(() => {
setValue(props.value)
}, [props.value])
useEffect(() => {
if (autoFocus) {
const searchSelf: HTMLInputElement | null = searchRef.current
searchSelf && searchSelf.focus()
}
}, [autoFocus])
const renderField = () => {
return (
change(e)}
onFocus={(e: any) => focus(e)}
onBlur={(e: any) => blur(e)}
/>
)
}
const renderLeftinIcon = () => {
if (!leftinIcon) return null
return (
clickLeftIcon('in-left', e)}
>
{leftinIcon}
)
}
const renderLeftoutIcon = () => {
if (!leftoutIcon) return null
return (
clickLeftIcon('out-left', e)}
>
{leftoutIcon}
)
}
const clickLeftIcon = (flag: TIconDirection, event: Event) => {
if (flag === 'in-left') {
onClickLeftinIcon && onClickLeftinIcon(value as string, event)
} else {
onClickLeftoutIcon && onClickLeftoutIcon(value as string, event)
}
}
const renderRightinIcon = () => {
if (!rightinIcon) return null
return (
clickRightIcon('in-right', e)}
style={mStyles.nut_search_icon_marginH}
>
{rightinIcon}
)
}
const renderRightoutIcon = () => {
if (!rightoutIcon) return null
return (
clickRightIcon('out-right', e)}
style={mStyles.nut_search_out_marginleft}
>
{rightoutIcon}
)
}
const clickRightIcon = (flag: TIconDirection, event: Event) => {
if (flag === 'in-left') {
onClickRightinIcon && onClickRightinIcon(value as string, event)
} else {
onClickRightoutIcon && onClickRightoutIcon(value as string, event)
}
}
const handleClear = () => {
return (
clearaVal(e)}
style={mStyles.nut_search_clear_marginright}
>
)
}
const clearaVal = (event: Event) => {
if (disabled || readOnly) {
return
}
setValue('')
onClear && onClear(event)
}
const renderRightLabel = () => {
if (actionText) {
return (
{actionText}
)
}
return null
}
const onKeypress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
const event = e.nativeEvent
if (typeof event.cancelable !== 'boolean' || event.cancelable) {
event.preventDefault()
}
onSearch && onSearch(value as string)
}
}
const cancel = () => {
onCancel && onCancel()
}
const renderLabel = () => {
if (label) {
return {label}
}
return null
}
return (
{renderLeftoutIcon()}
{renderLabel()}
{renderLeftinIcon()}
{renderField()}
{renderRightinIcon()}
{(clearable && value) ? handleClear(): null}
{renderRightoutIcon()}
{renderRightLabel()}
)
}
SearchBar.defaultProps = defaultProps
SearchBar.displayName = 'NutSearchBar'