Motomichi Works Blog

モトミチワークスブログです。その日学習したことについて書いている日記みたいなものです。

@radix-uiのコンポーネントにstyled-jsxでスタイル適用をしてみる

参照したページ

はじめに

スタイルが適用されていないヘッドレスなUIライブラリが流行ってきているみたいなので、ちょっと @radix-ui を使ってみます。

スタイルを適用してみる

試しにSwitchコンポーネント( Switch – Radix UI )にスタイル適用をしてみます。

disabledに固定値でfalse入れていたり、CSSはテキトーに書いているだけですが、styled-jsxを使う場合は以下のような感じで書けそうです。

import { useState } from 'react';
import * as Switch from '@radix-ui/react-switch';
import css from 'styled-jsx/css';

export function MySwitch() {
  const [isChecked, setIsChecked] = useState(true);

  const onChange = (checked: boolean) => {
    console.log('checked: ', checked);
    setIsChecked(checked);
  };

  return (
    <label className={`radix-switch ${className}`}>
      <Switch.Root
        className={`switch-track ${className}`}
        disabled={false}
        checked={isChecked}
        onCheckedChange={onChange}
      >
        <Switch.Thumb className={`switch-thumb ${className}`} />
      </Switch.Root>
      {styles}
    </label>
  );
}

const { className, styles } = css.resolve`
  .radix-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 24px;
    cursor: pointer;
  }

  .switch-track {
    width: 46px;
    height: 12px;
    cursor: pointer;
    background-color: #ccc;
    border: none;
    border-radius: 12px;
  }

  .switch-track[data-state='checked'] {
    background-color: #00f;
  }

  .switch-track[data-disabled] {
    background-color: #eee;
  }

  .switch-thumb {
    position: absolute;
    top: 50%;
    right: auto;
    left: 0;
    width: 20px;
    height: 20px;
    pointer-events: none;
    cursor: pointer;
    background: #fff;
    border: 1px solid #bcbdbd;
    border-radius: 100%;
    transform: translateY(-50%);
  }

  .switch-thumb[data-state='checked'] {
    right: 0;
    left: auto;
  }

  .switch-thumb[data-disabled] {
    background-color: #f5f5f5;
  }
`;

おわりに

実質CSSを書くだけでSwitchのコンポーネントができるので、フィールドの振る舞いから自分で書くのに比べたらだいぶ楽に感じました。