美文网首页
用typescript基于Modal封装的简单备注输入组件

用typescript基于Modal封装的简单备注输入组件

作者: AceKitty | 来源:发表于2022-06-01 16:03 被阅读0次
最终效果图

完整代码

import React, { forwardRef, Ref, useImperativeHandle, useState } from "react";
import {
    Modal,
    StyleSheet,
    Text,
    View, TouchableOpacity, TextInput, ScrollView, Dimensions
} from "react-native";

let width: number = Dimensions.get('window').width;
let w: number = width / 480;  //效果是基于480设计的

export type RemarkRef = {
        //通过ref调用  val:默认值   callback:回调方法
    show: (val?: string, callback?: Function) => void
}

export type RemarkProps = {
    maxLength?: number,  //备注最大长度
    placeholder?: string
}

const Remark = (props: RemarkProps, ref: Ref<RemarkRef>) => {

    let { maxLength = 255, placeholder } = props;
    const [modalVisible, setModalVisible] = useState(false);
    const [value, onChangeText] = useState('');
    const [cBack, setCBack] = useState<Function>(() => { });

    useImperativeHandle(ref, () => ({
        show(val?: string, callback?: Function) {
            onChangeText(val || "");
            if (callback) {
//此处赋值需注意 如果直接 setCBack(callback) 下面拿到的cBack为空
                setCBack(() => callback)
            }
            setModalVisible(true);
        }
    }))

    const save = () => {
        if (cBack) {
            cBack(value);
        }
        setModalVisible(false);
    }

    return (
        <Modal
            animationType="slide"
            transparent={true}
            visible={modalVisible}
            onRequestClose={() => {
                setModalVisible(!modalVisible);
            }}
        >
            <View style={styles.centeredView}>
                <View style={styles.contentView}>
                    <View style={styles.header}>
                        <TouchableOpacity activeOpacity={1} onPress={() => {
                            setModalVisible(false);
                        }}>
                            <Text style={styles.hTxt}>取消</Text>
                        </TouchableOpacity>
                        <TouchableOpacity activeOpacity={1} onPress={save}>
                            <Text style={styles.hTxt}>保存</Text>
                        </TouchableOpacity>

                    </View>
                    <Text style={styles.rtip}>备注</Text>
                    <View style={styles.line}></View>
                    <ScrollView style={styles.scrollView}>
                        <View style={styles.inputView}>
                            <TextInput
                                placeholder={placeholder || "请输入备注"}
                                multiline={true}
                                style={styles.rinput}
                                maxLength={maxLength}
                                onChangeText={text => onChangeText(text)}
                                value={value}
                                defaultValue={value}
                            />
                            <Text style={styles.tip}>{value.length + "/" + maxLength}</Text>
                        </View>
                    </ScrollView>
                </View>
            </View>
        </Modal >
    );
};

const styles = StyleSheet.create({
    centeredView: {
        flex: 1,
        justifyContent: 'flex-end',
        backgroundColor: 'rgba(149, 157, 165, 0.5)',
    },
    contentView: {
        height: 548 * w,
        maxHeight: 548 * w,
        flex: 1,
        backgroundColor: 'white',
        borderTopLeftRadius: 30 * w,
        borderTopRightRadius: 30 * w,
        overflow: "hidden",
        paddingBottom: 20 * w
    },
    header: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        marginTop: 25 * w,
        paddingHorizontal: 32 * w
    },
    hTxt: {
        fontSize: 22,
        color: '#1592A3'
    },
    rtip: {
        marginLeft: 32 * w,
        marginTop: 19 * w,
        fontSize: 25 * w
    },
    line: {
        height: StyleSheet.hairlineWidth,
        backgroundColor: '#EEEEEE',
        marginVertical: 16 * w
    },
    scrollView: {
        backgroundColor: '#F9F9F9'
    },
    inputView: {
        flex: 1,

    },
    rinput: {
        paddingHorizontal: 32 * w,
        paddingVertical: 16 * w,
        backgroundColor: 'white'
    },
    tip: {
        backgroundColor: 'white',
        color: '#999999',
        paddingHorizontal: 32 * w,
        paddingBottom: 20 * w,
        textAlign: 'right'
    }

});

export default forwardRef(Remark);

注意事项:

为防止整个modal页面顶到手机外面, 需要用ScrollView包裹需要滚动的View。

相关文章

网友评论

      本文标题:用typescript基于Modal封装的简单备注输入组件

      本文链接:https://www.haomeiwen.com/subject/uemxmrtx.html