みかづきブログ・カスタム

基本的にはちょちょいのほいです。

SCSSの@forをstyled-componentsで書き換える 🔁

Nuxt.js + styled-componentsで開発をしているのですが、SCSSのような感じで、

SCSS

ol {
  @for $i from 0 through 10 {
    li:nth-child(#{$i + 1}) {
      &:before {
        content: '#{$i}';
      }
    }
  }
}

こちらをstyled-componentsに書き換えてみると、

styled-components

const Ol = styled.ol`
  ${() => {
    let styles = '';

    for (let i = 0; i < 10; ++i) {
      styles += `
        li:nth-child(${ i + 1 }) {
          &:before {
            content: '${ i }';
          }
        }
      `;
    }

    return css`${ styles }`;
  }}
`;

こんな感じになるかと思います。
CSS単独でみると正直SCSSの方がシンプルで書きやすいのですが、styled-componentsはJavaScriptとCSSで変数を使いまわしやすいのが大きな利点となります。

追記

Github Copilot に任せてみたところ、

const Ol = styled.ol`
  ${[...Array(10)].map((_, i) => css`
    li:nth-child(${ i + 1 }) {
      &:before {
        content: '${ i }';
      }
    }
  `)};
`;

というコードになりました。

確かに、一旦変数(styles)に入れる必要はないので、css``を直接返すのは良さそうです。
mapを使って配列を作ると、

${[css`
    li:nth-child(${1}) {
      &:before {
        content: '1';
      }
    }
  `,
  css`
    li:nth-child(${2}) {
      &:before {
        content: '2';
      }
    }
  `,
  css`
    li:nth-child(${3}) {
      &:before {
        content: '3';
      }
    }
  `
  css`
    li:nth-child(${4}) {
      &:before {
        content: '4';
      }
    }
  `,
  css`
    li:nth-child(${5}) {
      &:before {
        content: '5';
      }
   }
  `
  css`
    li:nth-child(${6}) {
      &:before {
        content: '6';
      }
    }
  `,
  css`
    li:nth-child(${7}) {
      &:before {
        content: '7';
      }
    }
  `
  css`
    li:nth-child(${8}) {
      &:before {
        content: '8';
      }
    }
  `,
  css`
    li:nth-child(${9}) {
      &:before {
        content: '9';
      }
  }
  `,
  css`
    li:nth-child(${10}) {
      &:before {
        content: '10';
      }
  }
  `
]}

という配列が返されることになるのですが、styleed-componentsに配列を渡せることを知りませんでした。

ドキュメント を読んでも見当たらなのが気になりますが、JSXでは配列を埋め込めるので、同じような感じだと理解しました。

styled-components.com
ja.reactjs.org


今後は、Github Copilotに従ってみようと思います。