slate/components/core/Field.js

134 lines
3.7 KiB
JavaScript
Raw Normal View History

2021-06-09 01:53:30 +03:00
import * as React from "react";
2021-07-07 23:50:57 +03:00
import * as SVG from "~/common/svg";
2021-06-09 01:53:30 +03:00
2021-07-07 23:50:57 +03:00
import { P1 } from "~/components/system/components/Typography";
2021-06-09 01:53:30 +03:00
import { Input } from "~/components/system";
import { css } from "@emotion/react";
const STYLES_SMALL_TEXT = (theme) => css`
font-size: ${theme.typescale.lvlN1};
line-height: 15.6px;
`;
const STYLES_PASSWORD_VALIDATIONS = (theme) => css`
margin-top: 16px;
border: 1px solid ${theme.system.white};
background-color: white;
@supports ((-webkit-backdrop-filter: blur(25px)) or (backdrop-filter: blur(25px))) {
2021-07-07 22:58:14 +03:00
background-color: ${theme.semantic.bgBlurWhiteTRN};
2021-06-09 01:53:30 +03:00
backdrop-filter: blur(75px);
}
padding: 8px 12px;
border-radius: 8px;
`;
2021-07-07 23:50:57 +03:00
const STYLES_PASSWORD_VALIDATION = (theme) =>
css`
display: flex;
align-items: center;
& > * + * {
margin-left: 8px;
}
`;
2021-06-09 01:53:30 +03:00
const STYLES_CIRCLE = (theme) => css`
height: 8px;
width: 8px;
border-radius: 50%;
border: 1.25px solid ${theme.system.grayLight2};
`;
const STYLES_CIRCLE_SUCCESS = (theme) => css`
border: 1.25px solid ${theme.system.green};
`;
const STYLES_INPUT = (theme) => css`
2021-06-14 21:34:50 +03:00
background-color: rgba(242, 242, 247, 0.7);
2021-07-07 23:26:04 +03:00
box-shadow: ${theme.shadow.lightLarge};
2021-06-09 01:53:30 +03:00
border-radius: 8px;
&::placeholder {
2021-07-07 22:24:01 +03:00
color: ${theme.semantic.textGrayDark};
2021-06-09 01:53:30 +03:00
}
`;
const STYLES_INPUT_ERROR = (theme) => css`
2021-07-07 23:50:57 +03:00
background-color: rgba(242, 242, 247, 0.5);
border: 1px solid ${theme.system.red};
&::placeholder {
2021-05-27 11:20:34 +03:00
color: ${theme.semantic.textGrayDark};
2021-07-07 23:50:57 +03:00
}
2021-06-09 01:53:30 +03:00
`;
const STYLES_INPUT_SUCCESS = (theme) => css`
2021-07-07 23:50:57 +03:00
background-color: rgba(242, 242, 247, 0.5);
border: 1px solid ${theme.system.green};
&::placeholder {
2021-05-27 11:20:34 +03:00
color: ${theme.semantic.textGrayDark};
2021-07-07 23:50:57 +03:00
}
2021-06-09 01:53:30 +03:00
`;
2021-07-07 23:50:57 +03:00
const PasswordValidations = ({ validations }) => {
2021-06-09 01:53:30 +03:00
return (
2021-07-07 23:50:57 +03:00
<div css={STYLES_PASSWORD_VALIDATIONS}>
<P1 css={STYLES_SMALL_TEXT}>Passwords should</P1>
2021-06-09 01:53:30 +03:00
<div css={STYLES_PASSWORD_VALIDATION}>
<div css={[STYLES_CIRCLE, validations.validLength && STYLES_CIRCLE_SUCCESS]} />
2021-07-07 23:50:57 +03:00
<P1 css={STYLES_SMALL_TEXT}>Be at least 8 characters long</P1>
2021-06-09 01:53:30 +03:00
</div>
<div css={STYLES_PASSWORD_VALIDATION}>
<div
css={[
STYLES_CIRCLE,
validations.containsLowerCase && validations.containsUpperCase && STYLES_CIRCLE_SUCCESS,
]}
/>
2021-07-07 23:50:57 +03:00
<P1 css={STYLES_SMALL_TEXT}>Contain both uppercase and lowercase letters</P1>
2021-06-09 01:53:30 +03:00
</div>
<div css={STYLES_PASSWORD_VALIDATION}>
<div css={[STYLES_CIRCLE, validations.containsNumbers && STYLES_CIRCLE_SUCCESS]} />
2021-07-07 23:50:57 +03:00
<P1 css={STYLES_SMALL_TEXT}>Contain at least 1 number</P1>
2021-06-09 01:53:30 +03:00
</div>
<div css={STYLES_PASSWORD_VALIDATION}>
<div css={[STYLES_CIRCLE, validations.containsSymbol && STYLES_CIRCLE_SUCCESS]} />
2021-07-07 23:50:57 +03:00
<P1 css={STYLES_SMALL_TEXT}>Contain at least 1 symbol</P1>
2021-06-09 01:53:30 +03:00
</div>
</div>
);
};
export default function Field({
touched,
error,
success,
validations,
errorAs,
containerAs,
...props
}) {
2021-06-09 01:53:30 +03:00
const showError = touched && error;
const showSuccess = touched && !error;
2021-07-07 23:50:57 +03:00
const STYLES = React.useMemo(() => {
2021-06-09 01:53:30 +03:00
if (showError) return STYLES_INPUT_ERROR;
if (showSuccess) return STYLES_INPUT_SUCCESS;
2021-07-07 23:50:57 +03:00
return STYLES_INPUT;
2021-06-09 01:53:30 +03:00
}, [touched, error]);
const ContainerComponent = containerAs || "div";
const ErrorWrapper = errorAs || "div";
return (
<div>
<ContainerComponent>
2021-07-07 23:50:57 +03:00
<Input inputCss={STYLES} {...props} />
2021-06-09 01:53:30 +03:00
</ContainerComponent>
2021-07-07 23:50:57 +03:00
{props.name === "password" && validations ? (
<PasswordValidations validations={validations} />
) : (
2021-06-09 01:53:30 +03:00
<ErrorWrapper>
2021-07-07 23:50:57 +03:00
<P1 css={STYLES_SMALL_TEXT} style={{ marginTop: "8px" }}>
{(showError && error) || (showSuccess && success)}
2021-07-07 23:50:57 +03:00
</P1>
2021-06-09 01:53:30 +03:00
</ErrorWrapper>
)}
</div>
);
}