PromucFlow_constructor/app/client/src/components/designSystems/blueprint/InputComponent.tsx

163 lines
4.5 KiB
TypeScript
Raw Normal View History

import React from "react";
import styled from "styled-components";
2019-11-25 05:07:27 +00:00
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
2019-10-30 10:23:20 +00:00
import {
Intent,
NumericInput,
IconName,
InputGroup,
Button,
2019-10-31 05:28:11 +00:00
Label,
Text,
2019-10-30 10:23:20 +00:00
} from "@blueprintjs/core";
2019-11-25 05:07:27 +00:00
import { InputType } from "widgets/InputWidget";
2019-10-30 10:23:20 +00:00
/**
* All design system component specific logic goes here.
* Ex. Blueprint has a sperarate numeric input and text input so switching between them goes here
* Ex. To set the icon as currency, blue print takes in a set of defined types
* All generic logic like max characters for phone numbers should be 10, should go in the widget
*/
const InputComponentWrapper = styled.div`
&&&& div.bp3-input-group {
display: block;
margin: 0;
}
`;
2019-10-30 10:23:20 +00:00
class InputComponent extends React.Component<
InputComponentProps,
InputComponentState
> {
constructor(props: InputComponentProps) {
super(props);
this.state = { showPassword: false };
}
2019-10-31 05:28:11 +00:00
onTextChange = (event: React.ChangeEvent<HTMLInputElement>) => {
this.props.onValueChange(event.target.value);
};
onNumberChange = (valueAsNum: number, valueAsString: string) => {
this.props.onValueChange(valueAsString);
};
isNumberInputType(inputType: InputType) {
return (
2019-11-05 05:09:50 +00:00
inputType === "INTEGER" ||
inputType === "PHONE_NUMBER" ||
inputType === "NUMBER" ||
inputType === "CURRENCY"
2019-10-31 05:28:11 +00:00
);
}
getIcon(inputType: InputType) {
switch (inputType) {
case "PHONE_NUMBER":
return "phone";
case "SEARCH":
return "search";
case "EMAIL":
return "envelope";
default:
return undefined;
}
}
getType(inputType: InputType) {
switch (inputType) {
case "PASSWORD":
return this.state.showPassword ? "password" : "text";
case "EMAIL":
return "email";
case "SEARCH":
return "search";
default:
return "text";
}
}
2019-10-30 10:23:20 +00:00
render() {
return (
<InputComponentWrapper>
2019-11-05 05:09:50 +00:00
<Label className={"bp3-inline"}>
2019-12-03 04:41:10 +00:00
<span className={this.props.isLoading ? "bp3-skeleton" : ""}>
{this.props.label}
</span>
2019-10-31 05:28:11 +00:00
{this.isNumberInputType(this.props.inputType) ? (
<NumericInput
placeholder={this.props.placeholder}
min={this.props.minNum}
max={this.props.maxNum}
maxLength={this.props.maxChars}
disabled={this.props.disabled}
intent={this.props.intent}
2019-12-03 04:41:10 +00:00
className={this.props.isLoading ? "bp3-skeleton" : ""}
2019-10-31 05:28:11 +00:00
defaultValue={this.props.defaultValue}
onValueChange={this.onNumberChange}
leftIcon={
this.props.inputType === "PHONE_NUMBER"
? "phone"
: this.props.leftIcon
}
type={this.props.inputType === "PHONE_NUMBER" ? "tel" : undefined}
allowNumericCharactersOnly={true}
stepSize={this.props.stepSize}
/>
) : (
<InputGroup
placeholder={this.props.placeholder}
disabled={this.props.disabled}
maxLength={this.props.maxChars}
intent={this.props.intent}
onChange={this.onTextChange}
defaultValue={this.props.defaultValue}
2019-12-03 04:41:10 +00:00
className={this.props.isLoading ? "bp3-skeleton" : ""}
2019-10-31 05:28:11 +00:00
rightElement={
this.props.inputType === "PASSWORD" ? (
<Button
icon={"lock"}
onClick={() => {
this.setState({ showPassword: !this.state.showPassword });
}}
/>
) : (
undefined
)
}
type={this.getType(this.props.inputType)}
leftIcon={this.getIcon(this.props.inputType)}
/>
)}
</Label>
<Text>{this.props.errorMessage}</Text>
</InputComponentWrapper>
2019-10-30 10:23:20 +00:00
);
}
}
export interface InputComponentState {
showPassword?: boolean;
}
export interface InputComponentProps extends ComponentProps {
2019-10-31 05:28:11 +00:00
inputType: InputType;
2019-10-30 10:23:20 +00:00
disabled?: boolean;
intent?: Intent;
defaultValue?: string;
2019-10-31 05:28:11 +00:00
label: string;
2019-10-30 10:23:20 +00:00
leftIcon?: IconName;
allowNumericCharactersOnly?: boolean;
fill?: boolean;
2019-10-31 05:28:11 +00:00
errorMessage?: string;
maxChars?: number;
2019-10-30 10:23:20 +00:00
maxNum?: number;
minNum?: number;
2019-10-31 05:28:11 +00:00
onValueChange: (valueAsString: string) => void;
2019-10-30 10:23:20 +00:00
stepSize?: number;
placeholder?: string;
2019-12-03 04:41:10 +00:00
isLoading: boolean;
2019-10-30 10:23:20 +00:00
}
export default InputComponent;