【问题标题】:Floating labels using React and Ant Design使用 React 和 Ant Design 的浮动标签
【发布时间】:2020-03-01 03:32:21
【问题描述】:

对于我的 React 应用程序,我正在尝试使用来自 Antd 的模板构建一个带有 浮动标签 的表单,该模板具有不同的输入类型,仅使用样式来使标签浮动。到目前为止,我已经能够将标签放在输入后面,但是当我将转换 + 转换应用于我的 css 代码时,它似乎根本不起作用。

这是我的表格的一部分:

switch (data.inputType) {
        case 'input':
          return (
            <Form.Item key={`frmItem-${data.id}`}>
              <label htmlFor={data.id} className="floating-label">
                {data.label}
              </label>

              <Input
                key={`input-${data.id}`}
                id={data.id}
                className="floating-label-field"
                project-field={data.id}
                defaultValue={projectData[data.id]}
                onChange={handleUpload}
                // placeholder={data.placeholder}
                allowClear
              />
            </Form.Item>
          )

这是我的 style.js:

export const StyledFormDiv = styled.div`
  .ant-form-item {
    position: relative;
  }

  .ant-form-item-control {
    height: 50px;
  }

  /* Floating label */
  .floating-label {
    /* top: 0; */
    /* left: 0; */
    position: absolute;
    /* z-index: 500; */
    /* transform: translate(0, 25px) scale(1); */
    /* transition: color 200ms cubic-bezier(0, 0, 0.2, 1) 0ms, */
    /* transform 200ms cubic-bezier(0, 0, 0.2, 1) 0ms; */
    /* transition: width 0.4s ease; */
  }

  .floating-label-field {
    /* position: absolute; */
    /* touch-action: manipulation; */
    border-bottom: 1px solid #000 !important;
    border-radius: 0;
    box-shadow: none;
    width: 100%;
    /* transition: transform 0.25s, opacity 0.25s ease-in-out; */
    /* transform-origin: 0 0; */
    /* opacity: 0.5; */
    /* transition: padding-top 0.2s ease, margin-top 0.2s ease; */

    &::placeholder {
      color: transparent;
    }
  }

我认为 antd 可能有一些东西不允许我浮动标签,但我想要一种解决方法,不必安装另一个包或制作另一个组件。

【问题讨论】:

  • 请制作一个沙盒,尝试描述“浮动标签”的含义。对您来说,它可能被称为“浮动”,请向我们展示您除了标签之外的期望行为。
  • 另外,请注意,当 Form.Item 的行为类似于标签时,为 label 设置样式是没有意义的。

标签: javascript css node.js reactjs antd


【解决方案1】:

你可以为浮动标签写一个简单的组件,它可以包装antd输入。

看看这个 FloatLabel 组件,

import React, { useState } from "react";

import "./index.css";

const FloatLabel = props => {
  const [focus, setFocus] = useState(false);
  const { children, label, value } = props;

  const labelClass = focus || value ? "label label-float" : "label";

  return (
    <div
      className="float-label"
      onBlur={() => setFocus(false)}
      onFocus={() => setFocus(true)}
    >
      {children}
      <label className={labelClass}>{label}</label>
    </div>
  );
};

export default FloatLabel;

现在你可以像这样用 FloatLabel 组件包装你的 antd 输入,

<FloatLabel label="First Name" name="firstName" value={firstName}>
  <Input value={firstName} onChange={e => setFirstName(e.target.value)} />
</FloatLabel>

您可以查看此code sandbox 示例。

【讨论】:

    【解决方案2】:

    我知道为时已晚,但它可能对某人有所帮助。

    如果我从您的问题中理解正确,Ant 设计的浮动标签没有内置解决方案,所以我对表单字段和 CSS 进行了一些调整,我的代码如下。祝你好运!!!

    <FormItem label={""} className={"group-floating-label"}>
        {getFieldDecorator('name', {
            initialValue:'Jaison',
            rules: [{ required: true, message: 'Field required', whitespace:true }]
        })(
            <Input
                className="input-control"
                placeholder="."
                suffix={<label className="floating-label" htmlFor="name">Full Name</label>}
            />
        )}
    </FormItem>
    
    
    
    /* * * * * * * * * * * * * * * * * *
    Floating Label - .less
    * * * * * * * * * * * * * * * * * */
    
    //Custom version of floating label using the ant suffix method
    .group-floating-label {
        position: relative;
        margin-bottom: 30px !important;
    
        .input-control {
            .ant-input {
                display: block;
                width: 100%;
                line-height: 1.25;
                color: #000;
                background-color: #fff;
                background-image: none;
                background-clip: padding-box;
                border: 1px solid rgba(0, 0, 0, .15);
                border-radius: .25rem;
                transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
                border: 0;
                box-shadow: none;
                border-bottom: 1px solid #e8e8e8;
                border-radius: 0;
                .font-size(1.6);
                padding: 0;
    
                &.ant-input-disabled {
                    background-color: rgba(245, 245, 245, 0.36);
                    color: rgba(0, 0, 0, 0.36);
                }
    
                &:focus, &:hover {
                    box-shadow: none;
                    border-color: #4285f4;
                }
    
                &::-webkit-input-placeholder {
                    color: #fff;
    
                }
    
                &::-moz-placeholder {
                    color: #fff;
                }
    
                &:-ms-input-placeholder {
                    color: #fff;
                }
    
                &:focus + .ant-input-suffix, &:not(:placeholder-shown) + .ant-input-suffix {
                    .floating-label {
                        font-size: 85%;
                        transform: translate3d(0, -25px, 0);
                        color: rgba(0, 0, 0, .7);
                        padding-left: 0;
                    }
                }
            }
    
            @supports (-ms-ime-align:auto) {
                .ant-input-suffix {
                    .floating-label {
                        font-size: 85%;
                        transform: translate3d(0, -25px, 0);
                        color: rgba(0, 0, 0, .7);
                        padding-left: 0;
                    }
                }
            }
    
            &.show-placeholder {
                .ant-input {
                    &:focus {
                        &::-webkit-input-placeholder {
                            color: #ccc;
                            .font-size(1.3);
                        }
    
                        &::-moz-placeholder {
                            color: #ccc;
                            .font-size(1.3);
                        }
    
                        &:-ms-input-placeholder {
                            color: #ccc;
                            .font-size(1.3);
                        }
                    }
                }
            }
        }
    
        &.input-prefix {
            .prefix {
                display: inline-block;
                border: 1px solid #e8e8e8;
                border-radius: 20px;
                padding: 5px 10px;
                line-height: 10px;
                margin-right: 20px;
                position: absolute;
                left: 0;
                top: 4px;
                .font-size(1.6);
                text-align: center;
                z-index: 9;
                color: #000;
            }
    
            .input-control {
                .ant-input {
                    padding-left: 70px;
                }
            }
    
            .ant-input-suffix {
                .floating-label {
                    padding-left: 70px;
                }
            }
    
            .ant-input-prefix {
                left: 0;
                top: 0;
            }
        }
    
        .ant-input-suffix {
            left: 0;
            right: 0;
            top: 0;
    
            .floating-label {
                position: absolute !important;
                top: 0;
                padding: 0px;
                transition: all 200ms;
                color: rgba(0, 0, 0, 0.5);
                line-height: 30px;
                transform: translate3d(0, 0, 0);
            }
        }
    
        .has-error {
            .ant-input {
                box-shadow: none !important;
            }
    
            .input-control {
                .ant-input {
                    border-bottom: 2px solid red;
                }
            }
        }
    
        .ant-form-explain {
            margin-bottom: 0px;
    
            position: absolute;
            left: 0;
            right: 0;
            top: 35px;
        }
    
        .suffix-right {
            position: absolute;
            right: 0;
            top: 3px;
            cursor: pointer;
        }
    
        &.default-floated {
            .floating-label {
                transform: translate3d(0, -25px, 0) !important;
                padding-left: 0 !important;
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我的例子可能会帮助某人https://codesandbox.io/s/antd-float-label-forked-k8p00?file=/Example.js

      随时更新 css。

      表单组件

      import React from "react";
      import { Form } from "antd";
      
      import FloatInput from "./FloatInput";
      
      import "antd/dist/antd.css";
      import "./main.css";
      
      const validator = {
        require: {
          required: true,
          message: "Required"
        }
      };
      
      const Example = (props) => {
        return (
          <div className="example">
            <h3>Antd float labels Example</h3>
      
            <Form
              size="large"
              name="user_login"
              className="login-form"
              layout="vertical"
            >
              <Form.Item name="email" rules={[validator.require]} hasFeedback>
                <FloatInput
                  label="Email"
                  placeholder="Email here please"
                  name="email"
                />
              </Form.Item>
            </Form>
          </div>
        );
      };
      
      export default Example;
      
      

      浮动输入组件

      import React, { useState } from "react";
      import { Input } from "antd";
      
      import "./index.css";
      
      const FloatInput = (props) => {
        const [focus, setFocus] = useState(false);
        let { label, value, placeholder, type, required } = props;
      
        if (!placeholder) placeholder = label;
      
        const isOccupied = focus || (value && value.length !== 0);
      
        const labelClass = isOccupied ? "label as-label" : "label as-placeholder";
      
        const requiredMark = required ? <span className="text-danger">*</span> : null;
      
        return (
          <div
            className="float-label"
            onBlur={() => setFocus(false)}
            onFocus={() => setFocus(true)}
          >
            <Input onChange={props.onChange} type={type} defaultValue={value} />
            <label className={labelClass}>
              {isOccupied ? label : placeholder} {requiredMark}
            </label>
          </div>
        );
      };
      
      export default FloatInput;
      

      CSS

      .float-label {
        position: relative;
      }
      
      .label {
        font-weight: normal;
        position: absolute;
        pointer-events: none;
        left: 12px;
        top: 11px;
        transition: 0.2s ease all;
      }
      
      .as-placeholder {
        color: gray;
      }
      
      .as-label {
        top: -8px;
        font-size: 12px !important;
        background: white;
        padding: 0 4px;
        margin-left: -4px;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-30
        • 1970-01-01
        • 2019-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-06
        • 2020-03-11
        相关资源
        最近更新 更多