使用React&Formik创建自定义单选按钮

时间:2020-11-12 10:26:41

标签: javascript html reactjs formik

enter image description here

上面的示例是我创建的头像ui组件。 这基本上是一个圆形的div元素,该元素将child作为道具显示在此圆圈中。 它的边框也可以通过给出一个道具“ border = true”来切换。

我要做的是创建一个继承此UI元素的单选按钮,以便可以在React中的表单库formik中使用它。

由于我是Formik库的新手,所以我一直在努力实现该功能,以便将Formik的验证功能有效地合并到ui元素中。

enter image description here

这将是我想要实现的最终产品。

问题:

  1. 我知道一种实现此目的的方法是创建自定义CSS,但这不是我的目标。达到上述要求的最理想方法是什么?

  2. 如何获取自定义ui以与不是本地html输入元素的formik一起使用?

请告知。

到目前为止,这是我的代码。

import React from 'react';
import { DefaultAvatar } from './avatar.style';
import propTypes from 'prop-types';

const Avatar = ({
    imgUrl,
    sizes = 'md',
    bgColor = 'grey',
    border = false,
    borderColor = 'tertiary',
    borderWidth = '0.4rem',
    children,
    className,
    onClick,
}) => {
    return (
        <DefaultAvatar
            imgUrl={imgUrl}
            sizes={sizes}
            bgColor={bgColor}
            border={border}
            borderColor={borderColor}
            borderWidth={borderWidth}
            className={className}
            onClick={onClick}
        >
            {children}
        </DefaultAvatar>
    );
};

Avatar.propTypes = {
    imgUrl: propTypes.string,
    sizes: propTypes.oneOf(['lg', 'md', 'sm', 'xSm']),
    bgColor: propTypes.string,
    border: propTypes.bool,
    borderColor: propTypes.string,
    borderWidth: propTypes.string,
    children: propTypes.node,
    onClick: propTypes.func,
};

export default Avatar;

样式化身

import styled, { css } from 'styled-components';

const processSizes = (sizes) => {
    switch (sizes) {
        case 'xSm':
            return '2.4rem';
        case 'sm':
            return '4rem';
        case 'md':
            return '5.6rem';
        case 'lg':
            return '10.2rem';
    }
};

export const DefaultAvatar = styled.div`
    ${({
        theme,
        imgUrl,
        sizes,
        bgColor,
        border,
        borderColor,
        borderWidth,
        logoSize,
    }) => {
        return css`
            padding: ${theme.paddings.sm};
            background-color: ${theme.colors[bgColor]};
            border-radius: ${theme.borderRadius.roundedFull};
            width: ${() => processSizes(sizes)};
            height: ${() => processSizes(sizes)};
            border: ${border
                ? `solid ${borderWidth} ${theme.colors[borderColor]}` //TODO proportional borderWidth
                : 'none'};
            background: ${imgUrl
                ? `url(${imgUrl}) no-repeat center`
                : theme.colors[bgColor]};
            background-size: ${() => processSizes(sizes)};
            display: flex;
            justify-content: center;
            align-items: center;

            & > * {
                width: 100%;
                font-size: ${logoSize};
                text-align: center;
                justify-self: center;
                align-self: center;
            }
        `;
    }}
`;

0 个答案:

没有答案