注册
web

我看UI小姐姐就是在为难我这个切图仔

前言



image.png


改成这个样子


image.png


咱也不懂啊,这样更好看了吗,只能照着改了,谁让我只是个卑微的切图仔呢.


image.png


实现过程


刚开始我觉得很简单嘛,封装一个组件,用它包裹表单元素,比如Input、 Select、DatePicker等,然后修改css样式,把表单元素的border干掉,给外面的组件加上border不就搞定了,看起来也不是很复杂的样子.第一版长这样


image.png


发现问题了嘛,select下拉选项的宽度和表单元素不一样长,当然我觉得问题不大能用就行,但是在ui眼里那可不行,必须要一样长,不然不好看.
好吧,在我的据理力争下,我妥协啦,开始研究下一版.


image.png


在第一版的基础上我发现只有Select有这个问题,那就好办了,针对它单独处理就行了,解决方法思考了3种:



  • 第一种就是antd的Select可以设置dropdownStyle,通过获取父元素的宽度来设置下拉菜单的宽度,以此达到等长的目的
  • 第二种就是通过设置label元素为绝对定位,同时设置Select的paddingLeft
  • 还有一种就是通过在Select里添加css伪元素(注意这种方法需要把content里的中文转成unicode编码,不然可能会乱码)

最终我采用的是第二种方法,具体代码如下


import React, { CSSProperties, PropsWithChildren, useMemo } from 'react';
import { Form, FormItemProps, Col } from 'antd';
import styles from './index.module.less';

interface IProps extends FormItemProps {
label?: string;
style?: CSSProperties;
className?: string;
isSelect?: boolean;
noMargin?: boolean;
col?: number;
}
export const WrapFormComponent = ({ children, className, isSelect, style, col, noMargin = true, ...props }: PropsWithChildren<IProps>) => {
const labelWidth = useMemo(() => {
if (!isSelect || !props.label) return 11;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
context!.font = '12px PingFang SC';
const metrics = context!.measureText(props.label);
return metrics.width + (props.colon === undefined || props.colon ? 10 : 0) + 11;
}, [isSelect, props.label, props.colon]);
return (
<Col span={col}>
<Form.Item
style={{ '--label-length': labelWidth + 'px', marginBottom: noMargin ? 0 : '16px', ...style } as CSSProperties}
className={`${styles['wrap-form']} ${isSelect ? styles['wrap-form-select'] : ''} ${className || ''}`}
{...props}
>

{children}
</Form.Item>
</Col>

);
};


less代码


.wrap-form {
padding: 0 !important;
padding-left: 11px !important;
border: 1px solid #c1c7cd;
border-radius: 4px;

:global {
.ant-form-item-label {
display: inline-flex !important;
align-items: center !important;
}

.ant-form-item-label > label {
height: auto;
color: #919399;
font-weight: 400;
}

.ant-picker {
width: 100%;
}

.ant-input,
.ant-select-selector,
.ant-picker,
.ant-input-number {
border: none;
border-color: transparent !important;
}

.ant-input-affix-wrapper {
background: none;
border: none;
}
}
}

.wrap-form-select {
position: relative;
padding: 0 !important;

:global {
.ant-form-item-label {
position: absolute;
top: 50%;
left: 11px;
z-index: 1;
text-align: left;
transform: translateY(-50%);
}

.ant-select-selector {
padding-left: var(--label-length) !important;
}

.ant-select-selection-search {
left: var(--label-length) !important;
}

.ant-select-multiple .ant-select-selection-search {
top: -2px;
left: 0 !important;
margin-left: 0 !important;
}

.ant-select-multiple .ant-select-selection-placeholder {
left: var(--label-length) !important;
height: 28px;
line-height: 28px;
}
}
}

最后就变成这样了,完美解决,这下ui总不能挑刺儿了吧.


image.png

0 个评论

要回复文章请先登录注册