【发布时间】: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 转换为样式组件。特别是 focus 和 valid 选项。我真的不知道如何使用它们。当标签尺寸变化时,我也面临困难。它有时太左或有时太右。这是图片:
我真的不知道如何解决这些问题。
这是我基于 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