glass-app-manager
Version:
Informatica's Glass Framework CLI for bootstrapping
98 lines (82 loc) • 2.52 kB
JavaScript
// @flow
import * as React from "react";
import classNames from "classnames";
type Props = {
/**
* The HTML attribute type to pass to the input.
*/
type?: string,
/**
* Set true to set the input or textarea as disabled.
*/
disabled?: boolean,
/**
* Callback handler when the input changes.
*/
onChange?: (SyntheticEvent<HTMLInputElement | HTMLTextAreaElement>) => void,
/**
* Optionally specify the icon of your choice
* using a font library like archipelago-icons
* or font-awesome. Additionally, pass a render prop
* the customize the rendering behavior.
*/
icon?: string | (() => React.Node),
/**
* Specify the icon position.
*/
iconPosition?: "left" | "right",
/**
* Optionally specify a tabIndex prop.
*/
tabIndex?: string,
/**
* Callback handler when the button is clicked in the input field.
*/
onIconClick?: () => void,
/**
* Set true to use a textarea element instead of a basic input.
*/
textarea?: boolean,
};
const Icon = React.memo(({ onIconClick, icon, tabIndex }: Props) => {
const handleKeyUp = React.useCallback(
(e: SyntheticKeyboardEvent<HTMLInputElement>) => {
if (e && (e.keyCode === 13 || e.keyCode === 32) && onIconClick) {
onIconClick();
}
},
[onIconClick]
);
return typeof icon === "function" ? (
icon()
) : (
<i className={icon + " icon"} onClick={onIconClick} tabIndex={tabIndex} role="button" onKeyUp={handleKeyUp} />
);
});
const Textarea = (props: Props) => <textarea {...props} />;
function Input({ icon, type, iconPosition, onIconClick, textarea, className, ...rest }: Props) {
return (
<div
className={classNames(
"input",
icon ? "icon" : "",
icon && iconPosition === "left" ? "left" : "",
className
)}>
{textarea ? (
<Textarea {...rest} />
) : (
<>
<input type={type} {...rest} />
{icon ? <Icon icon={icon} onIconClick={onIconClick} {...rest} /> : null}
</>
)}
</div>
);
}
Input.defaultProps = {
type: "text",
disabled: false,
tabIndex: "0",
};
export default Input;