封装一个带有动画效果的DatePicker
在DatePicker获得焦点或者失去焦点时,拥有一个放大或者缩小的动画效果,
只是用到了简单的动画transform + translate实现,同理也可以封装input等
CustomDatePicker.tsx文件代码
import { DatePicker } from "antd";
import classnames from "classnames/bind";
import styles from "./index.module.less";
import { useState } from "react";
import { DatePickerProps } from "antd/es/date-picker";
const cx = classnames.bind(styles);
type CusDatePickerProps = {
title: string;
asterisk?: boolean;
} & DatePickerProps;
export const CusDatePicker = (props: CusDatePickerProps) => {
const { title, asterisk, value, onChange, format = "YYYY-MM-DD" } = props;
const [isFocus, setFocus] = useState(false);
const onFocus = () => {
setFocus(true);
};
const onBlur = () => {
setFocus(false);
};
return (
<div className={cx(styles.datePicker)}>
<div className={cx(styles.title, { [styles.focus]: isFocus || value })}>
{title}
{asterisk && <span className={styles.required}>*</span>}
</div>
<DatePicker
format={format}
className={styles.picker}
placeholder=" "
onFocus={onFocus}
onBlur={onBlur}
onChange={onChange}
{...props}
/>
</div>
);
};
less样式代码
.datePicker {
height: 70px;
background: #ffffff;
border: 1px solid #d4dde6;
box-shadow: 0px 26px 30px rgba(0, 0, 0, 0.06);
border-radius: 8px;
padding: 4px 16px;
display: flex;
align-items: center;
font-weight: 300;
font-size: 18px;
line-height: 28px;
position: relative;
.title {
position: absolute;
left: 16px;
top: 50%;
z-index: 100;
transform: translateY(-50%);
pointer-events: none; // 可点击下层
transition-property: top font-size;
transition-duration: 0.5s;
}
.focus {
.title;
top: 8px;
transform: translateY(0%);
font-size: 14px;
font-weight: 700;
line-height: 24px;
transition-property: top font-size;
transition-duration: 0.5s;
}
.picker {
width: 100%;
height: 100%;
padding: 4px 0;
}
.required {
color: #ed1b2e;
}
:global {
.ant-picker .ant-picker-input > input {
font-size: 18px;
font-weight: 400;
}
.ant-picker .ant-picker-suffix {
display: none;
}
.ant-picker {
border: 0;
align-items: flex-end;
}
.ant-picker-focused {
box-shadow: none;
}
}
}
:global {
.ant-form-item-has-error {
[class*="nano-input-wrapper"] {
border: 1px solid #ed1b2e;
}
}
}
使用
export default function Index() {
const [value, setValue] = useState<Dayjs>();
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: 400,
}}
>
<div style={{ width: 400 }}>
<CusDatePicker
title={"日期"}
value={value}
asterisk
onChange={(val) => setValue(val)}
/>
</div>
</div>
);
}