Css React.js&;样式化组件-样式化输入,其中包含元素(幻觉)
所以我想做的是创建一个样式化的输入,里面似乎有一个固定的文本(div/children/etc…) 一幅图像可以是自我解释的,所以这就是它现在的样子: 这看起来很简单,我的基本想法是: 我得到了一些包装器组件,它有两个子元素——输入本身和一些元素。 像这样:Css React.js&;样式化组件-样式化输入,其中包含元素(幻觉),css,reactjs,styled-components,Css,Reactjs,Styled Components,所以我想做的是创建一个样式化的输入,里面似乎有一个固定的文本(div/children/etc…) 一幅图像可以是自我解释的,所以这就是它现在的样子: 这看起来很简单,我的基本想法是: 我得到了一些包装器组件,它有两个子元素——输入本身和一些元素。 像这样: constinput=(props:InputProps)=>{ 返回( 厘米 ); }; 导出默认输入; 那么问题出在哪里呢? 问题是当我试图将宽度设置为此组件时。 它破坏一切 看起来是这样的: 因此包装器应该获得一个宽度属性,并将
constinput=(props:InputProps)=>{
返回(
厘米
);
};
导出默认输入;
那么问题出在哪里呢?
问题是当我试图将宽度设置为此组件时。
它破坏一切
看起来是这样的:
因此包装器应该获得一个宽度属性,并将输入和文本元素保留在其中。
以下是我创建的代码沙盒:
如果有人知道我做错了什么就好了
以下是一些文件:
Input.tsx
import React, { InputHTMLAttributes, CSSProperties } from "react";
import styled from "styled-components";
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
style?: CSSProperties;
label?: string;
value: string | number;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
text?: string;
isDisabled?: boolean;
hasError?: boolean;
errorLabel?: string | Function;
placeholder?: string;
width?: string;
}
const defaultProps: InputProps = {
text: "",
onChange: () => null,
value: ""
};
const Wrapper = styled.div<Partial<InputProps>>`
outline: 1px dashed red;
box-sizing: border-box;
justify-self: flex-start; // This is what prevent the child item strech inside grid column
border: 2px solid lightblue;
background: lightblue;
border-radius: 8px;
display: inline-flex;
align-items: center;
max-width: 100%;
width: ${({ width }) => width};
`;
const InputStyled = styled.input<Partial<InputProps>>`
box-sizing: border-box;
flex: 1;
outline: 1px dashed blue;
padding: 8px;
border: none;
border-radius: 8px;
max-width: 100%;
:focus {
outline: none;
}
`;
const InnerElement = styled.div`
outline: 1px dashed green;
box-sizing: border-box;
${({ children }) =>
children &&
`
padding: 0 8px;
font-size: 13px;
`};
`;
const Input = (props: InputProps) => {
return (
<Wrapper width={props.width}>
<InputStyled {...props} />
<InnerElement>{props.text}</InnerElement>
</Wrapper>
);
};
Input.defaultProps = defaultProps;
export default Input;
import * as React from "react";
import "./styles.css";
import Input from "./Input";
import styled from "styled-components";
const ContainerGrid = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 50px;
`;
export default function App() {
const [value, setValue] = React.useState("");
const handleChange = (e: any) => {
setValue(e.target.value);
};
const renderInputWithElement = () => {
return (
<ContainerGrid>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"60px"} // Play with this
text="inch"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"110px"} // Play with this
text="cm"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"200px"} // Play with this
text="mm"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"100%"} // Play with this
text="El"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"100%"} // Play with this
/>
</ContainerGrid>
);
};
return (
<div className="App">
<h1>StyledCode</h1>
<h3>Input with an element inside</h3>
<p>
This is kind of an illusion since input cannot have child element inside
of it really.
</p>
<hr style={{ marginBottom: "32px" }} />
{renderInputWithElement()}
</div>
);
}
import React,{inputtmlattributes,CSSProperties}来自“React”;
从“样式化组件”导入样式化;
导出接口InputProps扩展inputtmlattributes{
风格?:CSSProperties;
标签?:字符串;
值:字符串|编号;
onChange:(e:React.ChangeEvent)=>void;
文本?:字符串;
isDisabled?:布尔值;
hasError?:布尔值;
errorLabel?:字符串|函数;
占位符?:字符串;
宽度?:字符串;
}
常量defaultProps:InputProps={
正文:“,
onChange:()=>null,
值:“”
};
const Wrapper=styled.div`
轮廓:1px红色虚线;
框大小:边框框;
自我证明:灵活启动;//这就是防止子项在网格列中拉伸的原因
边框:2件纯色浅蓝色;
背景:浅蓝色;
边界半径:8px;
显示:内联flex;
对齐项目:居中;
最大宽度:100%;
宽度:${({width})=>width};
`;
const InputStyled=styled.input`
框大小:边框框;
弹性:1;
轮廓:1px蓝色虚线;
填充:8px;
边界:无;
边界半径:8px;
最大宽度:100%;
:焦点{
大纲:无;
}
`;
const InnerElement=styled.div`
轮廓:1px绿色虚线;
框大小:边框框;
${({children})=>
孩子们&&
`
填充:0 8px;
字体大小:13px;
`};
`;
常量输入=(props:InputProps)=>{
返回(
{props.text}
);
};
Input.defaultProps=defaultProps;
导出默认输入;
App.tsx
import React, { InputHTMLAttributes, CSSProperties } from "react";
import styled from "styled-components";
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
style?: CSSProperties;
label?: string;
value: string | number;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
text?: string;
isDisabled?: boolean;
hasError?: boolean;
errorLabel?: string | Function;
placeholder?: string;
width?: string;
}
const defaultProps: InputProps = {
text: "",
onChange: () => null,
value: ""
};
const Wrapper = styled.div<Partial<InputProps>>`
outline: 1px dashed red;
box-sizing: border-box;
justify-self: flex-start; // This is what prevent the child item strech inside grid column
border: 2px solid lightblue;
background: lightblue;
border-radius: 8px;
display: inline-flex;
align-items: center;
max-width: 100%;
width: ${({ width }) => width};
`;
const InputStyled = styled.input<Partial<InputProps>>`
box-sizing: border-box;
flex: 1;
outline: 1px dashed blue;
padding: 8px;
border: none;
border-radius: 8px;
max-width: 100%;
:focus {
outline: none;
}
`;
const InnerElement = styled.div`
outline: 1px dashed green;
box-sizing: border-box;
${({ children }) =>
children &&
`
padding: 0 8px;
font-size: 13px;
`};
`;
const Input = (props: InputProps) => {
return (
<Wrapper width={props.width}>
<InputStyled {...props} />
<InnerElement>{props.text}</InnerElement>
</Wrapper>
);
};
Input.defaultProps = defaultProps;
export default Input;
import * as React from "react";
import "./styles.css";
import Input from "./Input";
import styled from "styled-components";
const ContainerGrid = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 50px;
`;
export default function App() {
const [value, setValue] = React.useState("");
const handleChange = (e: any) => {
setValue(e.target.value);
};
const renderInputWithElement = () => {
return (
<ContainerGrid>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"60px"} // Play with this
text="inch"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"110px"} // Play with this
text="cm"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"200px"} // Play with this
text="mm"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"100%"} // Play with this
text="El"
/>
<Input
placeholder="input with element inside"
value={value}
onChange={handleChange}
width={"100%"} // Play with this
/>
</ContainerGrid>
);
};
return (
<div className="App">
<h1>StyledCode</h1>
<h3>Input with an element inside</h3>
<p>
This is kind of an illusion since input cannot have child element inside
of it really.
</p>
<hr style={{ marginBottom: "32px" }} />
{renderInputWithElement()}
</div>
);
}
import*as React from“React”;
导入“/styles.css”;
从“/Input”导入输入;
从“样式化组件”导入样式化;
const ContainerGrid=styled.div`
显示:网格;
网格模板柱:1fr 1fr;
栅隙:50px;
`;
导出默认函数App(){
const[value,setValue]=React.useState(“”);
常量handleChange=(e:any)=>{
设定值(即目标值);
};
常量renderInputWithElement=()=>{
返回(
);
};
返回(
样式代码
输入时包含一个元素
这是一种错觉,因为输入中不能包含子元素
真的。
{renderInputWithElement()}
);
}
我为您修复了它:
第一个问题是,您将相同的宽度设置为Wrapper和InputStyled(通过传递…道具),然后事情变得一团糟。显然,父元素和子元素旁边有其他元素,它们的宽度不能相同。InputStyled不会以您给定的宽度进行渲染,而是更小,因为InnerElement将其拉伸到左侧。
如果您需要传递所有的道具,包括宽度,您可以通过将宽度设置为unset来移除该宽度道具
<InputStyled {...props} width="unset" />
但是,填充会干扰宽度计算,这是另一个问题。见:
根据CSS基本框模型,元素的宽度和高度
应用于其内容框。填充不属于该内容
框并增加元素的总体大小
因此,如果将填充为100%宽度的元素设置为
填充将使其宽度超过其包含元素的100%。在里面
在您的上下文中,输入变得比其父级更广泛
你可以在那里提出解决方案。然而,一个简单的解决方案是使用小于填充宽度的宽度,因此宽度:calc(100%-16px)。这就成功了。所以我找到了答案,而且很简单 由于浏览器使用宽度初始化输入,因此会导致问题 使用flexbox behavor-输入元素不能收缩到其默认宽度以下,并被>强制溢出flex容器 因此我将
minwidth:0
添加到InputStyled
。
就这样
@对于你的答案,你是对的,宽度在错误的地方,我修正了,但是沙箱没有更新。我错过了。
无论如何,谢谢你的时间:)
这是我的固定沙箱:
再读一遍