import React from "react";
import styled from "styled-components";
import { IntentColors, labelStyle } from "constants/DefaultTheme";
import { ComponentProps } from "components/designSystems/appsmith/BaseComponent";
import {
Intent,
NumericInput,
IconName,
InputGroup,
Button,
Label,
Classes,
ControlGroup,
TextArea,
} from "@blueprintjs/core";
import { InputType } from "widgets/InputWidget";
import { WIDGET_PADDING } from "constants/WidgetConstants";
import { Colors } from "constants/Colors";
import ErrorTooltip from "components/editorComponents/ErrorTooltip";
import _ from "lodash";
import { INPUT_WIDGET_DEFAULT_VALIDATION_ERROR } from "constants/messages";
/**
* All design system component specific logic goes here.
* Ex. Blueprint has a separate 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((props) => (
))<{
numeric: boolean;
multiline: string;
hasError: boolean;
}>`
&&&& {
.${Classes.INPUT} {
box-shadow: none;
border: 1px solid;
border-color: ${({ hasError }) =>
hasError ? IntentColors.danger : Colors.GEYSER_LIGHT};
border-radius: ${(props) => props.theme.radii[1]}px;
height: ${(props) => (props.multiline === "true" ? "100%" : "inherit")};
width: 100%;
${(props) =>
props.numeric &&
`
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
border-right-width: 0px;
`}
&:active {
border-color: ${({ hasError }) =>
hasError ? IntentColors.danger : Colors.HIT_GRAY};
}
&:focus {
border-color: ${({ hasError }) =>
hasError ? IntentColors.danger : Colors.MYSTIC};
}
}
.${Classes.INPUT_GROUP} {
display: block;
margin: 0;
}
.${Classes.CONTROL_GROUP} {
justify-content: flex-start;
}
height: 100%;
align-items: center;
label {
${labelStyle}
flex: 0 1 30%;
margin: 7px ${WIDGET_PADDING * 2}px 0 0;
text-align: right;
align-self: flex-start;
max-width: calc(30% - ${WIDGET_PADDING}px);
}
}
`;
class InputComponent extends React.Component<
InputComponentProps,
InputComponentState
> {
constructor(props: InputComponentProps) {
super(props);
this.state = { showPassword: false };
}
setFocusState = (isFocused: boolean) => {
this.props.onFocusChange(isFocused);
};
onTextChange = (
event:
| React.ChangeEvent
| React.ChangeEvent,
) => {
this.props.onValueChange(event.target.value);
};
onNumberChange = (valueAsNum: number, valueAsString: string) => {
this.props.onValueChange(valueAsString);
};
isNumberInputType(inputType: InputType) {
return (
inputType === "INTEGER" ||
inputType === "NUMBER" ||
inputType === "CURRENCY"
);
}
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 ? "text" : "password";
case "EMAIL":
return "email";
case "SEARCH":
return "search";
default:
return "text";
}
}
onKeyDownTextArea = (e: React.KeyboardEvent) => {
const isEnterKey = e.key === "Enter" || e.keyCode === 13;
const { disableNewLineOnPressEnterKey } = this.props;
if (isEnterKey && disableNewLineOnPressEnterKey && !e.shiftKey) {
e.preventDefault();
}
if (typeof this.props.onKeyDown === "function") {
this.props.onKeyDown(e);
}
};
onKeyDown = (e: React.KeyboardEvent) => {
if (typeof this.props.onKeyDown === "function") {
this.props.onKeyDown(e);
}
};
private numericInputComponent = () => (
this.setFocusState(true)}
onBlur={() => this.setFocusState(false)}
onKeyDown={this.onKeyDown}
/>
);
private textAreaInputComponent = () => (