最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Floating labels using React and Ant Design - Stack Overflow

programmeradmin5浏览0评论

For my React app, I'm trying to build a form with floating labels using a template from Antd with different input types using only styles to make the labels float. So far I've been able to put the label behind the input, but when I apply transition + transform to my css code it seems to not work at all.

This is part of my form:

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>
          )

And this is my 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;
    }
  }

I think maybe there is something with antd not allowing me to float the labels, but I would like a workaround not having to install another package or making another component.

For my React app, I'm trying to build a form with floating labels using a template from Antd with different input types using only styles to make the labels float. So far I've been able to put the label behind the input, but when I apply transition + transform to my css code it seems to not work at all.

This is part of my form:

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>
          )

And this is my 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;
    }
  }

I think maybe there is something with antd not allowing me to float the labels, but I would like a workaround not having to install another package or making another component.

Share Improve this question edited Nov 4, 2019 at 20:00 María José Calderón asked Nov 4, 2019 at 19:24 María José CalderónMaría José Calderón 631 gold badge2 silver badges6 bronze badges 2
  • Please make a sandbox, try describing what "floating labels" means. For you, it may be called "floating", please show us the desired behavior that you except the labels. – Dennis Vash Commented Nov 5, 2019 at 7:08
  • Also, note that it's not making sense to style a label for that when Form.Item is acting like the label. – Dennis Vash Commented Nov 5, 2019 at 7:09
Add a comment  | 

3 Answers 3

Reset to default 11

You can write the simple component for the floating label which can wrap antd input.

Just take look this FloatLabel component,

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;

now you can wrap your antd input with FloatLabel component like this,

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

You can check this code sandbox example.

My example may help somebody https://codesandbox.io/s/antd-float-label-forked-k8p00?file=/Example.js

Feel free to update css.

Form component

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;

Float input component

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;
}

I know its too late, but it may help someone.

If I understood correctly from your question, there is no inbuilt solution for floating label with Ant design, So I had accomplished with some tweaks on the form fields and CSS, my code is below. Good luck!!!

<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;
        }
    }
}
发布评论

评论列表(0)

  1. 暂无评论