Text Styles
by cvalleskey
HTML
<div id="app"></div>
SCSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #F2F2F2;
padding: 20px;
font-family: 'Avenir Next', 'Arial', sans-serif;
font-size: 14px;
color: #252525;
}
#app {
/* border-radius: 4px; */
padding: 3vmin;
}
.text-styles {
width: 100%;
td, th {
border-bottom: 1px solid transparent;
transition: all 0.25s;
}
&:hover {
td,th {
border-color: #E6E6E6;
}
}
th {
border-bottom: 1px solid #D9D9D9;
padding: 0.5ex 8px 1.5ex;
font-size: 11px;
font-weight: 600;
color: #797979;
text-transform: uppercase;
vertical-align: bottom;
line-height: 1.2;
}
tr {
&.hover {
background: rgba(255,255,255,0.375);
}
}
.field {
/* border: 1px solid transparent; */
border: none;
background: transparent;
/* border-radius: 4px; */
margin: 0px 0;
padding: 0.75ex 8px;
line-height: 12px;
font-size: 12px;
width: 100%;
transition: all 0.125s;
font-size: 2ex;
height: 2.5rem;
display: flex;
align-items: stretch;
&:hover, &:focus {
background: rgba(255,255,255,0.5);
box-shadow: 0 0 0 1px transparent, inset 0 0 0 1px transparent;
/* background: #FFF; */
/* box-shadow: 1px 0 0 #E6E6E6, -1px 0 0 #E6E6E6; */
/* box-shadow: 0 0 3px rgba(0,0,0,0.125); */
/* border: 1px solid #D4D4D4; */
}
&:focus {
border-color: #719FE4;
/* outline: 3px solid #83B0F3; */
background: -webkit-linear-gradient(#f0f5ff, #FFF);
background: -moz-linear-gradient(#f0f5ff, #FFF);
background: -o-linear-gradient(#f0f5ff, #FFF);
background: linear-gradient(#f0f5ff, #FFF);
outline: none;
box-shadow: 0 0 0 1px #83B0F3, inset 0 0 0 1px #80AEF3;
z-index: 1;
position: relative;
}
}
.name {
width: 15%;
}
.font {
width: 30%;
}
}
React
function Field(props) {
function handleClick(e) {
e.currentTarget.select();
console.log('props', props);
}
function handleChange(e) {
console.log('change', e);
}
function handleOnKeyDown(e) {
console.log('keypress', e);
if(e.keyCode == 38) {
e.preventDefault();
e.currentTarget.value = parseInt(e.currentTarget.value, 10) + 1;
e.currentTarget.select();
} else if(e.keyCode == 40) {
e.preventDefault();
e.currentTarget.value = parseInt(e.currentTarget.value, 10) - 1;
e.currentTarget.select();
}
}
function customFont() {
if(props.useValueAsFont) {
return {
}
}
}
var styles = {
fontFamily: props.fontFamily,
fontSize: props.fontFamily? '3ex':'2ex'
}
return (
<input className="field" defaultValue={props.value} onKeyDown={handleOnKeyDown} onClick={handleClick} onChange={handleChange} style={styles}/>
);
}
function TextStylesList(props) {
function onMouseLeaveHandler(e) {
console.log('onMouseLeaveHandler', e);
e.currentTarget.className = "";
}
function onMouseEnterHandler(e) {
console.log('onMouseEnterHandler', e);
e.currentTarget.className = "hover";
}
const textStyles = props.textStyles;
const listItems = textStyles.map((textStyle) =>
<tr onMouseEnter={onMouseEnterHandler}
onMouseLeave={onMouseLeaveHandler}>
<td className="name"><Field value={textStyle.name} /></td>
<td className="font"><Field fontFamily={textStyle.font} value={textStyle.font}/></td>
<td className="font-weight"><Field value={textStyle.fontWeight}/></td>
<td className="font-size-min"><Field value={textStyle.fontSize.min}/></td>
<td className="font-size-max"><Field value={textStyle.fontSize.max}/></td>
<td className="line-height"><Field value={textStyle.lineHeight}/></td>
<td className="paragraph-spacing"><Field value={textStyle.paragraphSpacing}/></td>
</tr>
);
return (
<table className="text-styles">
...