// noPage import { LibComponent } from 'esoftplay/cache/lib/component/import'; import { LibTextstyle } from 'esoftplay/cache/lib/textstyle/import'; import { LibTheme } from 'esoftplay/cache/lib/theme/import'; import { LibUtils } from 'esoftplay/cache/lib/utils/import'; import React from 'react'; import { Platform, TextInput, TextStyle, View } from 'react-native'; export interface LibInputProps { icon?: (color: string) => any, label?: string, placeholder?: string, mask?: string, maskFrom?: 'start' | 'end', base?: boolean, children?: any, suffix?: string, onPress?: () => void, helper?: string allowFontScaling?: boolean, autoCapitalize?: "none" | "sentences" | "words" | "characters", autoCorrect?: boolean, autoFocus?: boolean, blurOnSubmit?: boolean, caretHidden?: boolean, contextMenuHidden?: boolean, defaultValue?: string, editable?: boolean, inactive?: boolean, keyboardType?: "default" | "email-address" | "numeric" | "phone-pad", maxLength?: number, multiline?: boolean, onSubmitEditing?: () => void, onChangeText?: (text: string, maskedText?: string) => void, placeholderTextColor?: string, returnKeyType?: "done" | "go" | "next" | "search" | "send", secureTextEntry?: boolean, selectTextOnFocus?: boolean, selectionColor?: string, style?: TextStyle, value?: string, } export interface LibInputState { hasFocus: boolean, error?: string, helper?: string } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md) untuk melihat dokumentasi*/ export default class m extends LibComponent { text: string ref: any constructor(props: LibInputProps) { super(props); this.state = { hasFocus: false } this.text = '' this.ref = React.createRef() this.getText = this.getText.bind(this); this.mask = this.mask.bind(this); this.unmask = this.unmask.bind(this); this.setError = this.setError.bind(this); this.clearError = this.clearError.bind(this); this.setHelper = this.setHelper.bind(this); this.clearHelper = this.clearHelper.bind(this); this.reverseString = this.reverseString.bind(this); this.getTextMasked = this.getTextMasked.bind(this); } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#getText) untuk melihat dokumentasi*/ getText(): string { return this.unmask(this.text) } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#getTextMasked) untuk melihat dokumentasi*/ getTextMasked(): string { return this.text } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#focus) untuk melihat dokumentasi*/ focus(): void { this.ref.focus() } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#blur) untuk melihat dokumentasi*/ blur(): void { this.ref.blur() } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#setHelper) untuk melihat dokumentasi*/ setHelper(msg: string): void { this.setState({ helper: msg }) } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#clearHelper) untuk melihat dokumentasi*/ clearHelper(msg: string): void { this.setState({ helper: undefined }) } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#setError) untuk melihat dokumentasi*/ setError(msg: string): void { this.setState({ error: msg }) } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#clearError) untuk melihat dokumentasi*/ clearError(): void { this.setState({ error: undefined }) } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#reverseString) untuk melihat dokumentasi*/ reverseString(str: string): string { let out = ''; for (let i = str.length - 1; i >= 0; i--) { out += str[i]; } return out; } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#mask) untuk melihat dokumentasi*/ mask(text: string): string { let { mask, maskFrom } = this.props if (mask) { if (!maskFrom) maskFrom = 'start' let rMask = mask let rText = this.unmask(text) if (maskFrom == 'end') { rMask = this.reverseString(mask) rText = this.reverseString(rText) } let maskedText = '' let _addRange = 0 let _addMaskChar = '' for (let i = 0; i < rMask.length; i++) { const iMask = rMask[i]; if (iMask == '#') { if (rText?.[i - _addRange] != undefined) { maskedText += _addMaskChar + rText[i - _addRange] } else { break } _addMaskChar = '' } else { _addMaskChar += iMask _addRange++ } } if (maskFrom == 'end') { maskedText = this.reverseString(maskedText) } this.ref.setNativeProps({ text: maskedText }) return maskedText } return text } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#unmask) untuk melihat dokumentasi*/ unmask(text: string): string { let _text = text let { mask } = this.props if (mask) { let masks = mask.match(/((?!\#).)/g) if (masks) { for (let i = 0; i < masks.length; i++) { _text = _text?.replace?.(new RegExp(LibUtils.escapeRegExp(masks[i]), 'g'), '') } } return _text } return _text } /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/input.md#setText) untuk melihat dokumentasi*/ setText(text: string): void { if (this.ref) { this.ref.setNativeProps({ text: this.mask(text) }) this.text = this.mask(text) } } componentDidUpdate(prevProps: LibInputProps, prevState: LibInputState): void { if (this.ref) { this.ref.setNativeProps({ text: this.mask(this.text) }) } if (this.props.base && this.text == '') { if (this.props.defaultValue != prevProps.defaultValue) { this.ref.setNativeProps({ text: this.mask(this.props.defaultValue) }) } } } componentDidMount(): void { super.componentDidMount() const timer = setTimeout(() => { if (this.props.defaultValue) { this.setText(this.props.defaultValue) } clearTimeout(timer) }); } render(): any { if (this.props.base) { const setups = { ref: (x) => this.ref = x, ...this.props, onChangeText: (t: string) => { this.text = this.mask(t) const unmaskedText = this.unmask(t) this.props.onChangeText(unmaskedText, this.text) }, maxLength: this.props.mask ? this.props.mask.length : undefined, } return this.props.children ? React.cloneElement(this.props.children, { ...setups }) : } const { label, placeholder, defaultValue, helper, editable, inactive, mask, suffix, icon, onPress } = this.props const { hasFocus, error } = this.state const stateHelper = this.state.helper let errorFocusOrIdle = error ? 'red' : hasFocus ? LibTheme._colorPrimary() : LibTheme._colorTextTertiary() let inputView = () => ( this.ref = e} onFocus={() => this.setState({ hasFocus: true })} onTouchEnd={() => editable == false && onPress ? onPress() : {}} onBlur={() => this.setState({ hasFocus: false })} placeholder={placeholder || ''} selectionColor={LibUtils.hexToRgba(LibTheme._colorPrimary(), 0.5)} placeholderTextColor={LibTheme._colorTextTertiary()} underlineColorAndroid={'transparent'} maxLength={mask ? mask.length : undefined} allowFontScaling={false} {...this.props} style={[{ outlineWidth: Platform.OS == 'web' ? 0 : undefined, paddingVertical: 8, marginBottom: 2, paddingRight: suffix ? (suffix.length * 14) : 0, fontSize: 17.5, color: error ? 'red' : inactive == true ? LibTheme._colorTextTertiary() : hasFocus ? LibTheme._colorPrimary() : LibTheme._colorTextPrimary(), }, { ...this.props.style }]} onChangeText={(e) => { this.text = this.mask(e) if (error != undefined) this.clearError() if (this.props.onChangeText) { this.props.onChangeText(this.unmask(e), this.text) } }} /> { suffix && } { error ? : } { stateHelper ? : } { helper ? : } ) return icon ? {icon(errorFocusOrIdle)} {inputView()} : inputView() } }