【问题标题】:React:Input label up in style componentReact:在样式组件中输入标签
【发布时间】:2020-06-26 09:54:54
【问题描述】:

我在我的应用程序中使用 React-typescript。对于造型,我使用Style-components。我真的是新的样式组件。很多语法对我来说都是新的。我通常使用css。我决定将我的 css 转换为样式组件。所以我可以使用它不同的组件。我创建了一个 Wrapper 组件,我将 Label 与样式组件放在一起。我还创建了两个组件,一个是 Input,另一个是 Textarea。我想在 Input 和 Textarea 组件中都使用 Wrapper 组件。我关注了一个youtube tutorial。我将 html 和 css 转换为 react-css 的地方。正如预期的那样工作正常。但我正在努力将反应 css 转换为样式组件。特别是 focusvalid 选项。我真的不知道如何使用它们。当标签尺寸变化时,我也面临困难。它有时太左或有时太右。这是图片:

.

我真的不知道如何解决这些问题。

这是我基于 React 组件的 Youtube 教程

import React from 'react'
import './new.css'

const Test = () => {

  return (
    <div className="main">
      <div className="input-group">
        <input type="text" id="firstname" className="inputField" autoComplete="off" required />
        <label htmlFor="name" className="labels">First name</label>
      </div>
    </div>
  )
}
export default Test;

这是css

.main{
position: relative;
}
.inputField{
  outline: none;
  padding: 16px 22px;
  border: 1px solid #dadce0;
  font-size:18px;
  border-radius:5px;
  }
.inputField:focus{
  border: 2px solid royalblue;
  }
.labels{
  color: #8d8d8d;
  position: absolute;
  top: 27px;
  left: 55px;
  background: #ffffff;
  transition: 300ms;
  transform: translate(-50%, -50%);
}
 .inputField:valid + .labels{ // I don't know how to use this `Valid` in style-component
  top: -1px;
  padding: 0 3px;
  font-size:14px;
  color: #8d8d8d;

}

 .inputField:focus + .labels { // I don't know how to use this `focus` in style-component
  top: -1px;
  padding: 0 3px;
  font-size:14px;
  color: royalblue;
  transition: 300ms;

}

这是我将标签样式与样式组件和其他要求一起使用的包装器组件。

import React from 'react';
import styled from 'styled-components';


const Container = styled.div`
  position: relative;
`
const Label = styled.label`
  display: block;
  color: #8d8d8d;
  background: #ffffff;
  position: absolute;
  left: 50px;
  top: 29px;
  pointer-events: none;
  transition: 300ms;
  transform: translate(-50%, -50%);
`

const Error = styled.p`
  color: red;
`

const Description = styled.p`
  color: blue;
`

export interface IInputWrapperProps {
  label?: string;
  required?: boolean;
  description?: string;
  error?: string;
  wrapperStyle?: React.CSSProperties;
  children?: JSX.Element;
}

export default ({
  label, error, description, children, required, wrapperStyle
}: IInputWrapperProps) => {
  return (
    <ErrorBoundary id="InputWrapperErrorBoundary">
      <div style={wrapperStyle}>
        <Container>
          <Label>
            {label} {required && <span style={{ color: 'red' }}> *</span>}
          </Label>
          {children}
        </Container>
        {description && <Description>{description}</Description>}
        {error && <Error>{error}</Error>}
      </div>
    </ErrorBoundary>
  );
}

这是我的输入组件样式与样式组件

    import React, { useState, memo } from "react";
import styled from "styled-components";
import InputWrapper, { IInputWrapperProps } from "../wrapper";
import { Label } from "../wrapper"

const Input = styled.input.attrs(() => ({
  className: 'text-input'
}))`
border: 1px solid #dadce0;
  background: #fdfdfd;
  font-size:18px;
  border-radius: 5px;
  box-shadow: none;
  padding: 16px 30px;
  outline: none;
  &:focus {
    border: 2px solid royalblue;
  }
  ${Label}:focus & {
    top: -12px;
    padding: 0 3px;
    font-size:14px;
    color: royalblue;
    transition: 300ms;
  }
`



export interface ITextInputProps extends IInputWrapperProps {
  value: string | undefined;
  onChange: (i: string) => void;
}

export default memo(({
  value, onChange, ...wrapperProps
}: ITextInputProps) => {

  return (
    <InputWrapper
      {...wrapperProps}
    >
      <div>
        <Input
          value={value}
          onChange={e => onChange(e.target.value)}
        />
      </div>
    </InputWrapper>
  )
});

这是我渲染这两个输入字段的父组件

        <InputTesting
                label="Frist Name"
                value={undefined}
                onChange={(i) => console.log(i)}
              />
              <br></br>
              <br></br>
              <InputTesting
                label="Hello"
                value={undefined}
                onChange={(i) => console.log(i)}
              />

【问题讨论】:

    标签: html css styles react-typescript


    【解决方案1】:

    在我回答这个问题之前,我需要说两件事:首先,我对你的 styled-components 代码了解不多,所以我将你的 react/CSS 代码转换为 react-typescript/styled-零件。其次,我没有理解“标签大小变化时的困难”是什么意思,所以我没有在答案中关注这一点。说了这么多,我们上代码吧。

    输入.tsx

    import React from 'react';
    import styled from 'styled-components';
    
    interface InputProps extends React.InputHTMLAttributes<HTMLInputElement>{
        id: string;
        label: string;
    }
    
    const InputGroup = styled.div`
      position: relative;
    `;
    
    const InputLabel = styled.label`
      color: #8d8d8d;
      position: absolute;
      top: 27px;
      left: 55px;
      background: #ffffff;
      transition: 300ms;
      transform: translate(-50%, -50%);
    `;
    
    const InputField = styled.input`
      outline: none;
      padding: 16px 22px;
      border: 1px solid #dadce0;
      font-size: 18px;
      border-radius: 5px;
    
      &:focus
      {
        border: 2px solid royalblue;
      }
    
      &:valid + ${InputLabel}
      {
        top: -1px;
        padding: 0 3px;
        font-size:14px;
        color: #8d8d8d;
      }
    
      &:focus + ${InputLabel}
      {
        top: -1px;
        padding: 0 3px;
        font-size:14px;
        color: royalblue;
        transition: 300ms;
      }
    `;
    
    const Input: React.FC<InputProps> = ({ id, label, ...rest }) => {
      return (
        <InputGroup>
          <InputField id={id} {...rest} />
          <InputLabel htmlFor={id} >{label}</InputLabel>
        </InputGroup>
      );
    }
    
    export default Input;
    
    

    这里的想法是创建一个内部已经有标签的输入组件。最初,我创建了一个名为 InputProps 的接口,它扩展了一个通用 InputElement 的所有属性,并强制父组件放置一个 id 和一个 label 属性.

    他们我使用 styled-components 从 youtube 上复制所有样式。要将伪类放在样式化组件上,您必须使用名为 parent selector 的 sass 功能。使用 & 符号,您可以引用父选择器。您必须使用的另一件事是styled-components reference。此功能将允许您引用代码中的样式标签。

    现在您已经创建了 Input 组件,让我们在 App 上使用它。

    App.tsx

    import React from 'react';
    import Input from './Input';
    
    function App() {
      return (
        <>
          <Input required type="text" label="First Name" id="first-name" />
          <Input required type="text" label="Hello" id="hello" />
        </>
      );
    }
    
    export default App;
    
    

    This is the final result.

    【讨论】:

      猜你喜欢
      • 2015-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      相关资源
      最近更新 更多