728x90
const theme = {
brandColor1: "#BE2525",
brandColor2: "#BE0000",
};
const backcolor = {
bgColor1: 'orange',
bgColor2: 'yellow'
}
const params = [theme, backcolor]
// strings 는 문자열이 있는 부분만 추출해서 배열에 저장함
// values 는 함수나 객체가 있는 부분만 추출해서 배열에 저장함
function css(strings, ...values) {
console.log(strings)
console.log(values)
return strings.reduce((res, str, i) => {
// 문자열이 있는 부분은 그냥 연결하고 함수나 객체가 있는 부분은 함수를 실행해서 얻은 반환값이나 객체의 프로퍼티 값을 연결함
return res + str + (values[i] ? values[i](params[i]) : "");
}, "");
}
const styles = css`
font-size: 1.2em;
color: ${(theme) => theme.brandColor2};
background: ${(backcolor) => backcolor.bgColor1}
`;
console.log(styles);
/* font-size: 1.2em;
color: #BE0000;
background: orange */const theme = {
brandColor1: "#BE2525",
brandColor2: "#BE0000",
};
const backcolor = {
bgColor1: 'orange',
bgColor2: 'yellow'
}
const params = [theme, backcolor]
// strings 는 문자열이 있는 부분만 추출해서 배열에 저장함
// values 는 함수나 객체가 있는 부분만 추출해서 배열에 저장함
function css(strings, ...values) {
console.log(strings)
console.log(values)
return strings.reduce((res, str, i) => {
// 문자열이 있는 부분은 그냥 연결하고 함수나 객체가 있는 부분은 함수를 실행해서 얻은 반환값이나 객체의 프로퍼티 값을 연결함
return res + str + (values[i] ? values[i](params[i]) : "");
}, "");
}
const styles = css`
font-size: 1.2em;
color: ${(theme) => theme.brandColor2};
background: ${(backcolor) => backcolor.bgColor1}
`;
console.log(styles);
/* font-size: 1.2em;
color: #BE0000;
background: orange */
app.js 파일을 위와 같이 작성하자!
const theme = { // font color
brandColor1: "#BE2525",
brandColor2: "#BE0000",
};
const backcolor = { // background color
bgColor1: '#eee',
bgColor2: '#bbb'
}
const props = { theme, backcolor } // props for styling
// strings 는 문자열이 있는 부분만 추출해서 배열에 저장함
// values 는 함수나 객체가 있는 부분만 추출해서 배열에 저장함
function cssWithProps(props, strings, ...values) {
return strings.reduce((res, str, i) => {
return res + str + (values[i] ? values[i](props) : ""); // 문자열이 있는 부분은 그냥 연결하고 함수나 객체가 있는 부분은 함수를 실행해서 얻은 반환값이나 객체의 프로퍼티 값을 연결함
}, "");
}
// build library like styled components with tag template literal and css function
const styled = {}
const tags = [
"div", "h1", "h2", "h3", "h4", "h5", "h6",
"a", "p", "button", "input", "span", "img",
]
setPropertiesOfStyledObject(styled, tags, props, buildStyledElement)
function setPropertiesOfStyledObject(styled, tags, props, buildStyledElement){
for(let tag of tags){
styled[tag] = (strings, ...values) => buildStyledElement(tag, props, strings, ...values) // closure: wrapping with tag and props
}
}
console.log(styled)
function buildElement(tag, style){
const el = document.createElement(tag)
el.style = style
return el
}
function buildStyledElement(tag, props, strings, ...values) {
const style = strings.reduce((res, str, i) => {
return res + str + (values[i] ? values[i](props) : ""); // props: { theme, backcolor }
}, "");
return buildElement(tag, style)
}
const divEl = styled.div`
width: 100%;
height: 500px;
font-size: 1.2em;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
${props => {
if(props.theme && props.backcolor){
const css = (strings, ...values) => cssWithProps(props, strings, ...values) // closure: wrapping with props
return css`
color: ${props => props.theme.brandColor2};
background: ${props => props.backcolor.bgColor1};
`
}
}}
`
console.log(divEl)
const buttonEl = styled.button`
width: 150px;
height: 50px;
outline: none;
border: none;
border-radius: 15px;
cursor: pointer;
content: "버튼";
color:#eee;
font-size: 1.5rem;
${props => {
if(props.backcolor){
const css = (strings, ...values) => cssWithProps(props, strings, ...values) // closure: wrapping with props
return css`
background: ${props => props.backcolor.bgColor2};
`
}
}}
`
console.log(buttonEl)
buttonEl.innerText = "click"
buttonEl.addEventListener('click', (e) => alert("you clicked this button !"))
const inputEl = styled.input`
width: 500px;
height: 50px;
outline: none;
border: 2px solid #bbb;
border-radius: 20px;
margin-top: 20px;
padding-left: 20px;
font-size: 1.5rem;
${props => {
if(props.theme && props.backcolor){
const css = (strings, ...values) => cssWithProps(props, strings, ...values) // closure: wrapping with props
return css`
color: ${props => props.theme.brandColor1};
background: ${props => props.backcolor.bgColor1};
`
}
}}
`
console.log(inputEl)
inputEl.autofocus = true
inputEl.placeholder = "Type something..."
document.body.appendChild(divEl)
divEl.append(buttonEl, inputEl)
app.js 파일을 위와 같이 작성하자!
728x90
'프론트엔드 > Javascript' 카테고리의 다른 글
요소 사이즈와 스크롤 (0) | 2024.02.25 |
---|---|
반복문 (loop) (0) | 2024.02.17 |
자바스크립트 문법 13 - 함수(function)의 활용 (0) | 2022.01.26 |
자바스크리트 문법 10 - 2차원 배열과 배열의 확장 (0) | 2022.01.13 |
자바스크립트 문법 9 - 배열(Array) 의 다양한 메서드 3 (분해와 융합) (0) | 2021.12.30 |