You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.6 KiB
TypeScript
106 lines
2.6 KiB
TypeScript
import * as React from "react";
|
|
import dashify from "dashify";
|
|
import { NumericFormat } from "react-number-format";
|
|
import type * as T from "./Input.types";
|
|
import { Box } from "../Box";
|
|
import { Label } from "../Label";
|
|
import { HelpText } from "../HelpText";
|
|
import { cx } from "../../utils";
|
|
import { inputStyles } from "./Input.styles";
|
|
import { match, P } from "ts-pattern";
|
|
|
|
const Input = React.forwardRef<HTMLInputElement, T.InputProps>(
|
|
(
|
|
{
|
|
label,
|
|
helpText,
|
|
money,
|
|
numericFormatOptions,
|
|
hideLabel = false,
|
|
symbol = "$",
|
|
currency = "USD",
|
|
hasError,
|
|
...props
|
|
},
|
|
forwardedRef
|
|
) => {
|
|
const htmlId = dashify(label);
|
|
const classes = cx(
|
|
inputStyles({ hasError }),
|
|
{
|
|
"pr-12": currency,
|
|
"text-right": money,
|
|
},
|
|
props.className
|
|
);
|
|
|
|
const moneyDecoratorsClasses = [
|
|
"pointer-events-none",
|
|
"absolute",
|
|
"inset-y-0",
|
|
"flex",
|
|
"items-center",
|
|
];
|
|
|
|
return (
|
|
<Box className={cx(["relative"])}>
|
|
<Label
|
|
className={cx({
|
|
"sr-only": hideLabel,
|
|
})}
|
|
htmlFor={htmlId}
|
|
>
|
|
{label}
|
|
</Label>
|
|
<Box
|
|
className={cx(["relative"], {
|
|
"mt-1": !hideLabel,
|
|
})}
|
|
>
|
|
{match(money)
|
|
.with(true, () => (
|
|
<>
|
|
<Box className={cx(["left-0", "pl-3"], moneyDecoratorsClasses)}>
|
|
<span className={cx(["text-mono-primary", "sm:text-sm"])}>
|
|
{symbol}
|
|
</span>
|
|
</Box>
|
|
<NumericFormat
|
|
id={htmlId}
|
|
className={classes}
|
|
valueIsNumericString
|
|
{...numericFormatOptions}
|
|
{...props}
|
|
// prefix={"$"}
|
|
getInputRef={forwardedRef}
|
|
/>
|
|
<Box
|
|
className={cx(["right-0", "pr-3"], moneyDecoratorsClasses)}
|
|
>
|
|
<span className={cx(["text-mono-primary", "sm:text-sm"])}>
|
|
{currency}
|
|
</span>
|
|
</Box>
|
|
</>
|
|
))
|
|
.otherwise(() => (
|
|
<input
|
|
{...props}
|
|
id={htmlId}
|
|
className={classes}
|
|
ref={forwardedRef}
|
|
/>
|
|
))}
|
|
</Box>
|
|
{match(helpText)
|
|
.with(P.not(P.nullish), () => (
|
|
<HelpText hasError={hasError}>{helpText}</HelpText>
|
|
))
|
|
.otherwise(() => null)}
|
|
</Box>
|
|
);
|
|
}
|
|
);
|
|
|
|
export { Input };
|