Simple enough question: I am trying to create inputs that are as large as the text supplied to them.
Sandbox: https://codesandbox.io/s/long-snowflake-6u13n?file=/src/Test.jsx
My design intention is to generate inputs dynamically and then allow the user to have styles specific to each input that visually help break up each sentence based on outside events. But before I can move forward, it's really important that my input container is only as large as the text within.
why not use a textarea? -- I have data that is particular to each sentence that I want to create unique styles for.
Any thoughts?
Here is an approach from plain HTML/CSS and a working snippet , hidding the value typed inside a span
behind the input
set in an absolute
position
. CSS can make both span
and input
matching the same lenght/width. Stretching/collapsing a parent (label
) will finish the job.
In the courtesy of @silvenon you may also find a react sample below the snippet
var val = document.querySelector('#test');
let tpl = document.querySelector('#tpl');
let text = val.value;
tpl.textContent= text;
val.addEventListener("input", function () {// onchange ...
let text= val.value;
//console.log(text);
tpl.textContent= text;
});
label {
display: inline-block;
position: relative;
min-width: 2em;
min-height: 1.4em;
}
#tpl {
white-space: pre;
/* max-width : could be wised to set a maximum width and overflow:hidden; */
}
#test {
font-family: inherit;
font-size: inherit;
position: absolute;
vertical-align: top;
top: 0;
left: 0;
width: 100%;
background: white;
}
<label><span id="tpl"></span><input id='test' value="Some test to try" ></label>
In the courtesy of @silvenon, you may find a react sample of that code.
const SentenceInput = styled.input`
padding: 0;
margin: 0;
border: none;
border: 1px solid black;
/* added styles */
font-family: inherit;
font-size: inherit;
position: absolute;
vertical-align: top;
top: 0;
left: 0;
width: 100%;
background: white;
`
const Label = styled.label`
display: inline-block;
position: relative;
min-width: 2em;
min-height: 1.4em;
`
const Template = styled.span`
white-space: pre;
/* max-width : could be wised to set a maximum width and overflow:hidden; */
`
const Sentence = ({ initialValue }) => {
const [value, setValue] = React.useState(initialValue)
return (
<Label>
<Template>{value}</Template>
<SentenceInput
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value)
}}
/>
</Label>
)
}