@dr.pogodin/react-utils
Version:
Collection of generic ReactJS components and utils
82 lines (79 loc) • 3.47 kB
JavaScript
import { useRef, useState } from 'react';
import themed from '@dr.pogodin/react-themes';
const defaultTheme = {
"context": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___context___-Jj9Dp",
"ad": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___ad___IOZUc8",
"hoc": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___hoc___nSzLXc",
"container": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___container___wW08uK",
"children": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___children___hCuQWP",
"input": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___input___oYQ-Uo",
"label": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___label___OTmX5n",
"error": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___error___7jrZ-X",
"errorMessage": "-dr-pogodin-react-utils___build-web-shared-components-Input-theme___errorMessage___qjYbwz"
};
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* Themeable input field, based on the standard HTML `<input>` element.
* @param [props.label] Input label.
* @param [props.theme] _Ad hoc_ theme.
* @param [props...] [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)
* @param [props...] Any other properties are passed to the underlying
* `<input>` element.
*/
const Input = ({
children,
error,
label,
ref,
testId,
theme,
...rest
}) => {
// NOTE: As of now, it is only updated when "theme.focused" is defined,
// as otherwise its value is not used.
const [focused, setFocused] = useState(false);
const localRef = useRef(null);
let containerClassName = theme.container;
// NOTE: As of now, "focused" can be true only when "theme.focused"
// is provided.
if (focused /* && theme.focused */) containerClassName += ` ${theme.focused}`;
if (!rest.value && theme.empty) containerClassName += ` ${theme.empty}`;
if (error) containerClassName += ` ${theme.error}`;
return /*#__PURE__*/_jsxs("div", {
className: containerClassName,
onFocus: () => {
// TODO: It does not really work if a callback-style `ref` is passed in,
// we need a more complex logic to cover that case, but for now this serves
// the case we need it for.
if (typeof ref === 'object') ref?.current?.focus();else localRef.current?.focus();
},
children: [label === undefined ? null : /*#__PURE__*/_jsx("div", {
className: theme.label,
children: label
}), /*#__PURE__*/_jsx("input", {
className: theme.input,
"data-testid": process.env.NODE_ENV === 'production' ? undefined : testId,
ref: ref ?? localRef
// TODO: Avoid the spreading later.
// eslint-disable-next-line react/jsx-props-no-spreading
,
...rest,
onBlur: theme.focused ? e => {
setFocused(false);
rest.onBlur?.(e);
} : rest.onBlur,
onFocus: theme.focused ? e => {
setFocused(true);
rest.onFocus?.(e);
} : rest.onFocus
}), error && error !== true ? /*#__PURE__*/_jsx("div", {
className: theme.errorMessage,
children: error
}) : null, children ? /*#__PURE__*/_jsx("div", {
className: theme.children,
children: children
}) : null]
});
};
export default themed(Input, 'Input', defaultTheme);
//# sourceMappingURL=index.js.map