Recode attr input with text field component
This commit is contained in:
		
							parent
							
								
									66102a9936
								
							
						
					
					
						commit
						469ebd2ac9
					
				@ -1,120 +1,59 @@
 | 
				
			|||||||
@import "../Theme/Theme.scss";
 | 
					@import "../Theme/Theme.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$line-min-height: 26px;
 | 
					$line-min-height: 24px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
div.attr-input {
 | 
					div.attr-input-root {
 | 
				
			||||||
	width: 100%;
 | 
					    display: flex;
 | 
				
			||||||
	display: flex;
 | 
					    justify-content: space-between;
 | 
				
			||||||
	min-height: $line-min-height;
 | 
					    align-items: center;
 | 
				
			||||||
	padding: 5px 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	div.input-intro {
 | 
					    input {
 | 
				
			||||||
		width: 50%;
 | 
					        display: block;
 | 
				
			||||||
		height: 100%;
 | 
					        width: 100%;
 | 
				
			||||||
        min-height: $line-min-height;
 | 
					 | 
				
			||||||
		max-width: 220px;
 | 
					 | 
				
			||||||
		display: flex;
 | 
					 | 
				
			||||||
		align-items: center;
 | 
					 | 
				
			||||||
        padding-right: 5px;
 | 
					 | 
				
			||||||
        box-sizing: border-box;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    div.root-content {
 | 
					 | 
				
			||||||
        width: 50%;
 | 
					 | 
				
			||||||
        height: 100%;
 | 
					        height: 100%;
 | 
				
			||||||
        max-width: 180px;
 | 
					        border: none;
 | 
				
			||||||
 | 
					        outline: none;
 | 
				
			||||||
 | 
					        background-color: transparent;
 | 
				
			||||||
        min-height: $line-min-height;
 | 
					        min-height: $line-min-height;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        div.input-content {
 | 
					    input:focus {
 | 
				
			||||||
            box-sizing: border-box;
 | 
					        border: none;
 | 
				
			||||||
            border: 1px solid transparent;
 | 
					        background-color: transparent;
 | 
				
			||||||
            border-radius: 3px;
 | 
					    }
 | 
				
			||||||
            overflow: hidden;
 | 
					 | 
				
			||||||
            display: flex;
 | 
					 | 
				
			||||||
            justify-content: space-between;
 | 
					 | 
				
			||||||
            align-items: center;
 | 
					 | 
				
			||||||
            height: $line-min-height;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
            input {
 | 
					 | 
				
			||||||
                width: 100%;
 | 
					 | 
				
			||||||
                height: 100%;
 | 
					 | 
				
			||||||
                border: none;
 | 
					 | 
				
			||||||
                outline:none;
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
            input:focus {
 | 
					 | 
				
			||||||
                border: none;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
            div.button-left, div.button-right {
 | 
					 | 
				
			||||||
                min-height: $line-min-height;
 | 
					 | 
				
			||||||
                height: 100%;
 | 
					 | 
				
			||||||
                display: flex;
 | 
					 | 
				
			||||||
                justify-content: center;
 | 
					 | 
				
			||||||
                align-items: center;
 | 
					 | 
				
			||||||
                vertical-align: middle;
 | 
					 | 
				
			||||||
                cursor: pointer;
 | 
					 | 
				
			||||||
                user-select: none;
 | 
					 | 
				
			||||||
                padding: 0 3px;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        div.input-content.error {
 | 
					 | 
				
			||||||
            border: 1px solid $lt-red;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        div.input-content.focus {
 | 
					    div.button-left, div.button-right {
 | 
				
			||||||
            border: 1px solid $lt-blue;
 | 
					        min-height: $line-min-height;
 | 
				
			||||||
        }
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
        div.err-message {
 | 
					        justify-content: center;
 | 
				
			||||||
            color: $lt-red;
 | 
					        align-items: center;
 | 
				
			||||||
            padding-top: 5px;
 | 
					        vertical-align: middle;
 | 
				
			||||||
            min-height: $line-min-height;
 | 
					        cursor: pointer;
 | 
				
			||||||
        }
 | 
					        user-select: none;
 | 
				
			||||||
 | 
					        padding: 0 3px;
 | 
				
			||||||
        div.error-view {
 | 
					 | 
				
			||||||
            border-radius: 3px;
 | 
					 | 
				
			||||||
            overflow: hidden;
 | 
					 | 
				
			||||||
            display: flex;
 | 
					 | 
				
			||||||
            align-items: center;
 | 
					 | 
				
			||||||
            height: $line-min-height;
 | 
					 | 
				
			||||||
            text-overflow: ellipsis;
 | 
					 | 
				
			||||||
            word-wrap: none;
 | 
					 | 
				
			||||||
            word-break: keep-all;
 | 
					 | 
				
			||||||
            white-space: nowrap;
 | 
					 | 
				
			||||||
            cursor:not-allowed;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            span {
 | 
					 | 
				
			||||||
                padding-left: 8px;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
div.dark.attr-input {
 | 
					div.dark.text-field-root {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	div.input-content, div.error-view,
 | 
						input {
 | 
				
			||||||
	div.input-content input {
 | 
					 | 
				
			||||||
		background-color: $lt-bg-color-lvl3-dark;
 | 
							background-color: $lt-bg-color-lvl3-dark;
 | 
				
			||||||
		color: $lt-font-color-normal-dark;
 | 
							color: $lt-font-color-normal-dark;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    div.error-view:hover,
 | 
					 | 
				
			||||||
	div.button-left:hover, div.button-right:hover {
 | 
						div.button-left:hover, div.button-right:hover {
 | 
				
			||||||
		background-color: $lt-bg-color-lvl2-dark;
 | 
							background-color: $lt-bg-color-lvl2-dark;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
div.light.attr-input {
 | 
					div.light.text-field-root {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	div.input-content, div.error-view,
 | 
						input {
 | 
				
			||||||
	div.input-content input {
 | 
					 | 
				
			||||||
		background-color: $lt-bg-color-lvl3-light;
 | 
							background-color: $lt-bg-color-lvl3-light;
 | 
				
			||||||
		color: $lt-font-color-normal-light;
 | 
							color: $lt-font-color-normal-light;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    div.error-view:hover,
 | 
					 | 
				
			||||||
	div.button-left:hover, div.button-right:hover {
 | 
						div.button-left:hover, div.button-right:hover {
 | 
				
			||||||
		background-color: $lt-bg-color-lvl2-light;
 | 
							background-color: $lt-bg-color-lvl2-light;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,12 @@
 | 
				
			|||||||
import { Component, ReactNode } from "react";
 | 
					import { Component, ReactNode } from "react";
 | 
				
			||||||
import { FontLevel, Theme } from "@Component/Theme/Theme";
 | 
					 | 
				
			||||||
import "./AttrInput.scss";
 | 
					 | 
				
			||||||
import { Icon } from "@fluentui/react";
 | 
					import { Icon } from "@fluentui/react";
 | 
				
			||||||
import { Localization, AllI18nKeys } from "@Component/Localization/Localization";
 | 
					import { Localization, AllI18nKeys } from "@Component/Localization/Localization";
 | 
				
			||||||
import { ObjectID } from "@Model/Renderer";
 | 
					import { ObjectID } from "@Model/Renderer";
 | 
				
			||||||
 | 
					import { TextField, ITextFieldProps } from "../TextField/TextField";
 | 
				
			||||||
 | 
					import "./AttrInput.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface IAttrInputProps {
 | 
					interface IAttrInputProps extends ITextFieldProps {
 | 
				
			||||||
    id?: ObjectID;
 | 
					    id?: ObjectID;
 | 
				
			||||||
    keyI18n: AllI18nKeys;
 | 
					 | 
				
			||||||
    infoI18n?: AllI18nKeys;
 | 
					 | 
				
			||||||
    value?: number | string;
 | 
					    value?: number | string;
 | 
				
			||||||
	isNumber?: boolean;
 | 
						isNumber?: boolean;
 | 
				
			||||||
    maxLength?: number;
 | 
					    maxLength?: number;
 | 
				
			||||||
@ -16,15 +14,14 @@ interface IAttrInputProps {
 | 
				
			|||||||
    max?: number;
 | 
					    max?: number;
 | 
				
			||||||
    min?: number;
 | 
					    min?: number;
 | 
				
			||||||
    step?: number;
 | 
					    step?: number;
 | 
				
			||||||
    disable?: boolean;
 | 
					 | 
				
			||||||
    disableI18n?: AllI18nKeys;
 | 
					 | 
				
			||||||
    valueChange?: (value: this["isNumber"] extends true ? number : string) => any;
 | 
					    valueChange?: (value: this["isNumber"] extends true ? number : string) => any;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AttrInput extends Component<IAttrInputProps> {
 | 
					class AttrInput extends Component<IAttrInputProps> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private value: string = "";
 | 
					    private value: string = "";
 | 
				
			||||||
    private error: ReactNode;
 | 
					    private error?: AllI18nKeys;
 | 
				
			||||||
 | 
					    private errorOption?: Record<string, string>;
 | 
				
			||||||
    private numberTestReg = [/\.0*$/, /\.\d*[1-9]+0+$/];
 | 
					    private numberTestReg = [/\.0*$/, /\.\d*[1-9]+0+$/];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private numberTester(value: string) {
 | 
					    private numberTester(value: string) {
 | 
				
			||||||
@ -33,17 +30,21 @@ class AttrInput extends Component<IAttrInputProps> {
 | 
				
			|||||||
            this.numberTestReg[1].test(value);
 | 
					            this.numberTestReg[1].test(value);
 | 
				
			||||||
    } 
 | 
					    } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private check(value: string): ReactNode {
 | 
					    private check(value: string): AllI18nKeys | undefined {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 长度校验
 | 
					        // 长度校验
 | 
				
			||||||
        const maxLength = this.props.maxLength ?? 32;
 | 
					        const maxLength = this.props.maxLength ?? 32;
 | 
				
			||||||
        if (value.length > maxLength) {
 | 
					        if (value.length > maxLength) {
 | 
				
			||||||
            return <Localization i18nKey="Input.Error.Length" options={{ num: maxLength.toString() }} />
 | 
					            this.error = "Input.Error.Length";
 | 
				
			||||||
 | 
					            this.errorOption = { num: maxLength.toString() };
 | 
				
			||||||
 | 
					            return this.error;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const minLength = this.props.minLength ?? 1;
 | 
					        const minLength = this.props.minLength ?? 1;
 | 
				
			||||||
        if (value.length < minLength) {
 | 
					        if (value.length < minLength) {
 | 
				
			||||||
            return <Localization i18nKey="Input.Error.Length.Less" options={{ num: minLength.toString() }} />
 | 
					            this.error = "Input.Error.Length.Less";
 | 
				
			||||||
 | 
					            this.errorOption = { num: minLength.toString() };
 | 
				
			||||||
 | 
					            return this.error;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this.props.isNumber) {
 | 
					        if (this.props.isNumber) {
 | 
				
			||||||
@ -51,17 +52,22 @@ class AttrInput extends Component<IAttrInputProps> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // 数字校验
 | 
					            // 数字校验
 | 
				
			||||||
            if (this.numberTester(value)) {
 | 
					            if (this.numberTester(value)) {
 | 
				
			||||||
                return <Localization i18nKey="Input.Error.Not.Number" />
 | 
					                this.error = "Input.Error.Not.Number";
 | 
				
			||||||
 | 
					                return this.error;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 最大值校验
 | 
					            // 最大值校验
 | 
				
			||||||
            if (this.props.max !== undefined && praseNumber > this.props.max) {
 | 
					            if (this.props.max !== undefined && praseNumber > this.props.max) {
 | 
				
			||||||
                return <Localization i18nKey="Input.Error.Max" options={{ num: this.props.max.toString() }} />
 | 
					                this.error = "Input.Error.Max";
 | 
				
			||||||
 | 
					                this.errorOption = { num: this.props.max.toString() };
 | 
				
			||||||
 | 
					                return this.error;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 最小值校验
 | 
					            // 最小值校验
 | 
				
			||||||
            if (this.props.min !== undefined && praseNumber < this.props.min) {
 | 
					            if (this.props.min !== undefined && praseNumber < this.props.min) {
 | 
				
			||||||
                return <Localization i18nKey="Input.Error.Min" options={{ num: this.props.min.toString() }} />
 | 
					                this.error = "Input.Error.Min";
 | 
				
			||||||
 | 
					                this.errorOption = { num: this.props.min.toString() };
 | 
				
			||||||
 | 
					                return this.error;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -102,41 +108,33 @@ class AttrInput extends Component<IAttrInputProps> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private renderInput() {
 | 
					    private renderInput() {
 | 
				
			||||||
        return <>
 | 
					        return <>
 | 
				
			||||||
            <div className={"input-content" + (this.error ? ` error` : "")}>
 | 
					            {
 | 
				
			||||||
                {
 | 
					                this.props.isNumber ? <div
 | 
				
			||||||
                    this.props.isNumber ? <div
 | 
					                    className="button-left"
 | 
				
			||||||
                        className="button-left"
 | 
					                    onClick={() => this.changeValue(-1)}
 | 
				
			||||||
                        onClick={() => this.changeValue(-1)}
 | 
					                >
 | 
				
			||||||
                    >
 | 
					                    <Icon iconName="ChevronLeft"></Icon>
 | 
				
			||||||
                        <Icon iconName="ChevronLeft"></Icon>
 | 
					                </div> : null
 | 
				
			||||||
                    </div> : null
 | 
					            }
 | 
				
			||||||
                }
 | 
					            <input
 | 
				
			||||||
                <input
 | 
					                className="input"
 | 
				
			||||||
                    className="input"
 | 
					                value={this.value}
 | 
				
			||||||
                    value={this.value}
 | 
					                style={{
 | 
				
			||||||
                    style={{
 | 
					                    padding: this.props.isNumber ? "0 3px" : "0 8px"
 | 
				
			||||||
                        padding: this.props.isNumber ? "0 3px" : "0 8px"
 | 
					                }}
 | 
				
			||||||
                    }}
 | 
					                onChange={(e) => {
 | 
				
			||||||
                    onChange={(e) => {
 | 
					                    this.value = e.target.value;
 | 
				
			||||||
                        this.value = e.target.value;
 | 
					                    this.error = this.check(e.target.value);
 | 
				
			||||||
                        this.error = this.check(e.target.value);
 | 
					                    this.handelValueChange();
 | 
				
			||||||
                        this.handelValueChange();
 | 
					                }}
 | 
				
			||||||
                    }}
 | 
					            ></input>
 | 
				
			||||||
                ></input>
 | 
					            {
 | 
				
			||||||
                {
 | 
					                this.props.isNumber ? <div
 | 
				
			||||||
                    this.props.isNumber ? <div
 | 
					                    className="button-right"
 | 
				
			||||||
                        className="button-right"
 | 
					                    onClick={() => this.changeValue(1)}
 | 
				
			||||||
                        onClick={() => this.changeValue(1)}
 | 
					                >
 | 
				
			||||||
                    >
 | 
					                    <Icon iconName="ChevronRight"></Icon>
 | 
				
			||||||
                        <Icon iconName="ChevronRight"></Icon>
 | 
					                </div> : null
 | 
				
			||||||
                    </div> : null
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            { 
 | 
					 | 
				
			||||||
                this.error ? 
 | 
					 | 
				
			||||||
                    <div className="err-message">
 | 
					 | 
				
			||||||
                        {this.error}
 | 
					 | 
				
			||||||
                    </div> : null
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        </>
 | 
					        </>
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -166,33 +164,19 @@ class AttrInput extends Component<IAttrInputProps> {
 | 
				
			|||||||
        this.error = this.check(value.toString());
 | 
					        this.error = this.check(value.toString());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private renderErrorInput() {
 | 
					 | 
				
			||||||
        return <div className="error-view">
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                this.props.disableI18n ? 
 | 
					 | 
				
			||||||
                <Localization i18nKey={this.props.disableI18n}/> :
 | 
					 | 
				
			||||||
                <span>{this.props.value}</span>
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public render(): ReactNode {
 | 
						public render(): ReactNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return <Theme
 | 
							return <TextField
 | 
				
			||||||
            className="attr-input"
 | 
					            {...this.props}
 | 
				
			||||||
            fontLevel={FontLevel.normal}
 | 
					            className="attr-input-root"
 | 
				
			||||||
 | 
					            customHoverStyle
 | 
				
			||||||
 | 
					            errorI18n={this.error}
 | 
				
			||||||
 | 
					            errorI18nOption={this.errorOption}
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
            <div className="input-intro">
 | 
					            {
 | 
				
			||||||
                <Localization i18nKey={this.props.keyI18n}/>
 | 
					                this.renderInput()
 | 
				
			||||||
            </div>
 | 
					            }
 | 
				
			||||||
            <div className="root-content">
 | 
					        </TextField>;
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    this.props.disable ? 
 | 
					 | 
				
			||||||
                        this.renderErrorInput() :
 | 
					 | 
				
			||||||
                        this.renderInput()
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </Theme>
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										84
									
								
								source/Component/TextField/TextField.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								source/Component/TextField/TextField.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					@import "../Theme/Theme.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$line-min-height: 26px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.text-field-root {
 | 
				
			||||||
 | 
					    min-height: $line-min-height;
 | 
				
			||||||
 | 
						width: 100%;
 | 
				
			||||||
 | 
						display: flex;
 | 
				
			||||||
 | 
						padding: 5px 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    div.text-field-intro {
 | 
				
			||||||
 | 
					        min-height: $line-min-height;
 | 
				
			||||||
 | 
							width: 50%;
 | 
				
			||||||
 | 
							height: 100%;
 | 
				
			||||||
 | 
							max-width: 220px;
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							align-items: center;
 | 
				
			||||||
 | 
					        padding-right: 5px;
 | 
				
			||||||
 | 
					        box-sizing: border-box;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    div.text-field-container {
 | 
				
			||||||
 | 
					        min-height: $line-min-height;
 | 
				
			||||||
 | 
					        width: 50%;
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        max-width: 180px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        div.text-field-content {
 | 
				
			||||||
 | 
					            min-height: $line-min-height;
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					            height: 100%;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        div.text-field-content-styled {
 | 
				
			||||||
 | 
					            box-sizing: border-box;
 | 
				
			||||||
 | 
					            border: 1px solid transparent;
 | 
				
			||||||
 | 
					            border-radius: 3px;
 | 
				
			||||||
 | 
					            overflow: hidden;
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        div.text-field-content-disable {
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            span {
 | 
				
			||||||
 | 
					                display: block;
 | 
				
			||||||
 | 
					                padding-left: 8px;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        div.text-field-content-error {
 | 
				
			||||||
 | 
					            border: 1px solid $lt-red;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        div.text-field-error-message {
 | 
				
			||||||
 | 
					            padding-top: 5px;
 | 
				
			||||||
 | 
					            color: $lt-red;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.dark.text-field-root {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						div.text-field-content-styled {
 | 
				
			||||||
 | 
							background-color: $lt-bg-color-lvl3-dark;
 | 
				
			||||||
 | 
							color: $lt-font-color-normal-dark;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						div.text-field-content-hover-styled:hover {
 | 
				
			||||||
 | 
							background-color: $lt-bg-color-lvl2-dark;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.light.text-field-root {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						div.text-field-content-styled {
 | 
				
			||||||
 | 
							background-color: $lt-bg-color-lvl3-light;
 | 
				
			||||||
 | 
							color: $lt-font-color-normal-light;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						div.text-field-content-hover-styled:hover {
 | 
				
			||||||
 | 
							background-color: $lt-bg-color-lvl2-light;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										104
									
								
								source/Component/TextField/TextField.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								source/Component/TextField/TextField.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					import { Component, ReactNode, RefObject } from "react";
 | 
				
			||||||
 | 
					import { FontLevel, Theme } from "@Component/Theme/Theme";
 | 
				
			||||||
 | 
					import { AllI18nKeys, Localization } from "@Component/Localization/Localization";
 | 
				
			||||||
 | 
					import "./TextField.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ITextFieldProps {
 | 
				
			||||||
 | 
					    className?: string;
 | 
				
			||||||
 | 
					    keyI18n: AllI18nKeys;
 | 
				
			||||||
 | 
					    infoI18n?: AllI18nKeys;
 | 
				
			||||||
 | 
					    disableI18n?: AllI18nKeys;
 | 
				
			||||||
 | 
					    disableI18nOption?: Record<string, string>;
 | 
				
			||||||
 | 
					    errorI18n?: AllI18nKeys;
 | 
				
			||||||
 | 
					    errorI18nOption?: Record<string, string>;
 | 
				
			||||||
 | 
					    targetRef?: RefObject<HTMLDivElement>;
 | 
				
			||||||
 | 
					    customStyle?: boolean;
 | 
				
			||||||
 | 
					    customHoverStyle?: boolean;
 | 
				
			||||||
 | 
					    onClick?: () => any;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TextField extends Component<ITextFieldProps> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private renderInput() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const classList: string[] = ["text-field-content"];
 | 
				
			||||||
 | 
					        if (this.props.className) {
 | 
				
			||||||
 | 
					            classList.push(this.props.className);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!this.props.customStyle) {
 | 
				
			||||||
 | 
					            classList.push("text-field-content-styled");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!this.props.customHoverStyle) {
 | 
				
			||||||
 | 
					            classList.push("text-field-content-hover-styled");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.props.errorI18n) {
 | 
				
			||||||
 | 
					            classList.push("text-field-content-error");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return <div
 | 
				
			||||||
 | 
					            className={classList.join(" ")}
 | 
				
			||||||
 | 
					            ref={this.props.targetRef}
 | 
				
			||||||
 | 
					            style={{ cursor: "pointer" }}
 | 
				
			||||||
 | 
					            onClick={this.props.onClick}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            { this.props.children }
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private renderDisable() {
 | 
				
			||||||
 | 
					        return <div
 | 
				
			||||||
 | 
					            className={
 | 
				
			||||||
 | 
					                `${
 | 
				
			||||||
 | 
					                    "text-field-content"
 | 
				
			||||||
 | 
					                } ${
 | 
				
			||||||
 | 
					                    "text-field-content-styled"
 | 
				
			||||||
 | 
					                } ${
 | 
				
			||||||
 | 
					                    "text-field-content-hover-styled"
 | 
				
			||||||
 | 
					                } ${
 | 
				
			||||||
 | 
					                    "text-field-content-disable"
 | 
				
			||||||
 | 
					                }`
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ref={this.props.targetRef}
 | 
				
			||||||
 | 
					            style={{ cursor: "not-allowed" }}
 | 
				
			||||||
 | 
					            onClick={this.props.onClick}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <Localization
 | 
				
			||||||
 | 
					                i18nKey={this.props.disableI18n ?? "Common.No.Unknown.Error"}
 | 
				
			||||||
 | 
					                options={this.props.disableI18nOption}
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private renderError() {
 | 
				
			||||||
 | 
					        return <div className="text-field-error-message">
 | 
				
			||||||
 | 
					            <Localization
 | 
				
			||||||
 | 
					                i18nKey={this.props.errorI18n ?? "Common.No.Unknown.Error"}
 | 
				
			||||||
 | 
					                options={this.props.errorI18nOption}
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public render(): ReactNode {
 | 
				
			||||||
 | 
					        return <>
 | 
				
			||||||
 | 
					            <Theme className="text-field-root" fontLevel={FontLevel.normal}>
 | 
				
			||||||
 | 
					                <div className="text-field-intro">
 | 
				
			||||||
 | 
					                    <Localization i18nKey={this.props.keyI18n}/>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div className="text-field-container">
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        this.props.disableI18n ? 
 | 
				
			||||||
 | 
					                            this.renderDisable() :
 | 
				
			||||||
 | 
					                            this.renderInput()
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        this.props.errorI18n ?
 | 
				
			||||||
 | 
					                            this.renderError() :
 | 
				
			||||||
 | 
					                            undefined
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </Theme>
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { TextField, ITextFieldProps };
 | 
				
			||||||
@ -44,6 +44,7 @@ const EN_US = {
 | 
				
			|||||||
    "Panel.Title.Group.Details.View": "Group",
 | 
					    "Panel.Title.Group.Details.View": "Group",
 | 
				
			||||||
    "Panel.Info.Group.Details.View": "Edit view group attributes",
 | 
					    "Panel.Info.Group.Details.View": "Edit view group attributes",
 | 
				
			||||||
    "Common.No.Data": "No Data",
 | 
					    "Common.No.Data": "No Data",
 | 
				
			||||||
 | 
					    "Common.No.Unknown.Error": "Unknown error",
 | 
				
			||||||
    "Common.Attr.Title.Basic": "Basic properties",
 | 
					    "Common.Attr.Title.Basic": "Basic properties",
 | 
				
			||||||
    "Common.Attr.Title.Spatial": "Spatial property",
 | 
					    "Common.Attr.Title.Spatial": "Spatial property",
 | 
				
			||||||
    "Common.Attr.Title.Individual.Generation": "Individual generation",
 | 
					    "Common.Attr.Title.Individual.Generation": "Individual generation",
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,7 @@ const ZH_CN = {
 | 
				
			|||||||
    "Panel.Title.Group.Details.View": "群",
 | 
					    "Panel.Title.Group.Details.View": "群",
 | 
				
			||||||
    "Panel.Info.Group.Details.View": "编辑查看群属性",
 | 
					    "Panel.Info.Group.Details.View": "编辑查看群属性",
 | 
				
			||||||
    "Common.No.Data": "暂无数据",
 | 
					    "Common.No.Data": "暂无数据",
 | 
				
			||||||
 | 
					    "Common.No.Unknown.Error": "未知错误",
 | 
				
			||||||
    "Common.Attr.Title.Basic": "基础属性",
 | 
					    "Common.Attr.Title.Basic": "基础属性",
 | 
				
			||||||
    "Common.Attr.Title.Spatial": "空间属性",
 | 
					    "Common.Attr.Title.Spatial": "空间属性",
 | 
				
			||||||
    "Common.Attr.Title.Individual.Generation": "个体生成",
 | 
					    "Common.Attr.Title.Individual.Generation": "个体生成",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user