ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Tagged 템플릿 리터럴
    프론트엔드/Javascript 2022. 7. 16. 08:25
    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
Designed by Tistory.