24
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Radix UIが作った新しいUIライブラリのThemesがとても良い!

Posted at

はじめに

Radix UIのPrimitivesを使ったことはありますか?
ヘッドレスなUIコンポーネントを提供してくれるライブラリとして有名で単にRadix UIとも呼ばれます(似たようなライブラリとしては最近でたArk UIなどがあります)。
このようなライブラリはUIを見た目と振る舞いに分けたうちの振る舞いだけを実装したコンポーネントを提供しています。そのため、Material UIやChakra UIのようなスタイリングも含むUIコンポーネントライブラリでは強制されていたスタイリング方法から抜け出して自由度を持ったスタイリングができるとして人気です。

そんなライブラリを開発していたRadix UIですが、新たにThemesと呼ばれるコンポーネントライブラリの提供を2023年の8月8日から開始しました。

この記事ではThemesの使い方と特徴を簡単に紹介します。

Themes

Themesの説明が遅れてしまいました。ThemesはUIコンポーネントライブラリです。
Primitiveとは異なりスタイリングも振る舞いも兼ねたMaterial UIChakra UIに近いライブラリです。

コンポーネントの設計指針は以下のように掲げられております。

An open-source component library optimized for fast development, easy maintenance, and accessibility.
迅速な開発、容易なメンテナンス、アクセシビリティのために最適化されたオープンソースのコンポーネントライブラリです。

スタイリングは純粋なCSSを用いて行われており、他のUIコンポーネントライブラリでよく使われているemotionなどに依存していないところも特徴です。

さらにRSCにも対応しています。対応していると言っても全てのコンポーネントにuse clientディレクティブを用いた暫定的な対応ではなく、クライアント側のコンポーネントとサーバー側のコンポーネントをちゃんと使い分けた実装がなされています。

Themesには便利なページがあります。

全体でカスタマイズ可能な項目を選択しながらコンポーネントの一覧を見ることができるplaygroundです。一覧性が高く、標準からカスタマイズした姿が見られるのでとても感動しました。開発する前に全貌を把握できるのでとても便利です。

導入する

Nextjsのプロジェクトを用いて導入を進めてみます。他のプロジェクトでも同様に導入可能です。

アプリの下準備としてNextjsのプロジェクトを作ります。

pnpm create next-app

いくつか質問されますがほとんどはデフォルトで回答します。tailwindcssは利用しないのでnoを選択します。
noを選択してもCSS Modulesを用いたプロジェクトが建つのでglobals.csspage.modules.cssを削除します。さらにlayout.tsxからファイルの参照を消して、page.tsxからファイルの参照とJSXを書き換えるために空にしておきます。

src/app/page.tsx
export default function Home() {
  return <></>
}

これでNextjsアプリの作成とスタイリングの排除が完了しました。

次にThemesを導入していきます。
まずはパッケージのインストールです。

pnpm install @radix-ui/themes

続いて、layout.tsxにアプリ全体で設定したいThemesが提供するCSSを配置します。

import '@radix-ui/themes/styles.css';

他のフレームワークの場合はどこにアクセスした時も呼び出すところに配置してください(remixだとroot.tsxとか)。

そして、Themes全体のカスタマイズのためにThemeコンポーネントをlayout.tsxに定義します。

src/app/layout.tsx
import { Theme } from '@radix-ui/themes';
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import '@radix-ui/themes/styles.css';

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
            <Theme>
              {children}
            </Theme>
          </body>
    </html>
  )
}

これで準備は完了です。好きなコンポーネントを@radix-ui/themesから呼び出して利用していきましょう!

import { Flex, Text, Button } from '@radix-ui/themes';

export default function MyApp() {
  return (
    <Flex direction="column" gap="2">
      <Text>Hello from Radix Themes :)</Text>
      <Button>Let's go</Button>
    </Flex>
  );
}

スクリーンショット 2023-08-10 19.41.01.png

Themeによるカスタマイズ

Themeコンポーネントではアプリ全体の基本となる色、カラーモード、ビジュアルスタイルを設定します。
Themeコンポーネントの設定をするときはThemePanelコンポーネントを用いることをお勧めします。
ThemePanelコンポーネントはThemeコンポーネントでカスタマイズ可能な項目を変更するパネルを画面に表示させられます。
スクリーンショット 2023-08-10 19.13.50.png
開発初期の段階ではかなり助かる機能だと考えています。

アプリケーションの中心となる色としてアクセントカラーを、グレースケールの中心カラーとしてグレーカラーを選択します。

<Theme accentColor="lime" grayColor="olive">

アクセントカラーは全23種類あります。選択した色に対応して文字の色も決まります。
グレーカラーは全6種類あります。
アクセントカラーとグレーカラーの組み合わせに悩んだ場合はおすすめの組み合わせが提供されているので参考にしてください。

カラーモード

デフォルトではライトモードに設定されています。Themeappearancedarkに設定することでダークモードに変更できます。

<Theme accentColor="lime" grayColor="olive" appearance="dark">

カラーモードの設定はクライアント側で要素に対するクラスの追加によって行われるのでエラーが発生します。
以下のようにhtmlsuppressHydrationWarningを追加して抑制させてください。

<html lang="en" suppressHydrationWarning>

カードなどの背景

Themesではデフォルトの状態ではカードやテーブルの背景は半透過しています。
スクリーンショット 2023-08-10 19.29.42.png
透過させたくない場合はpanelBackgroundsolidにすることで等価を失わせられます。

<Theme panelBackground="solid">

スクリーンショット 2023-08-10 19.30.51.png

角丸

コンポーネントの境界の外側の角に対する丸みを決めます。

<Theme radius="medium">

コンポーネント

コンポーネントは大きくレイアウトとタイポグラフィ、コンポーネントの3つに分けられます。

レイアウトはBoxFlexのようなコンポーネントを組み合わせるときや整理する時に利用するコンポーネントです。

タイポグラフィはTextHeadingのようなテキストを表すためのコンポーネントです。

コンポーネントはAccordionCheckBoxのような機能を持ったコンポーネントです。

レイアウトにSectionがあったり、タイポグラフィにEmがあったりhtmlの要素のセマンティクスに配慮しやすいコンポーネントが多くアクセシビリティへの配慮を感じました。

スタイリング

コンポーネントへのスタイリングは引数を用いて行います。量が多いので頭出しだけですが、Boxに対して4pxのpaddingを設けたい場合は以下のように設定します。

<Box p="1" />

p1を指定して4pxのpaddingを実現しました。この値はThemesで指定されたCSS変数によって定まりました。
このケースではデフォルトのファイルにある--space-1を元に4pxとなりました。

space.css
.radix-themes {
  --space-1: calc(4px * var(--scaling));
  --space-2: calc(8px * var(--scaling));
  --space-3: calc(12px * var(--scaling));
  --space-4: calc(16px * var(--scaling));
  --space-5: calc(24px * var(--scaling));
  --space-6: calc(32px * var(--scaling));
  --space-7: calc(40px * var(--scaling));
  --space-8: calc(48px * var(--scaling));
  --space-9: calc(64px * var(--scaling));
}

このようにコンポーネントで指定する値の多くはThemesが定義したCSS変数によって決まります。それをtheme-config.cssファイルに上書きして定義してカスタマイズできます。theme-config.csslayout.tsxのようなルートファイルで@radix-ui/themes/styles.cssと合わせて呼び出す必要があります。

theme-config.css
.radix-themes {
  --space-1: 4px;
}

CSS変数がまとまったデフォルトの設定はこちらに書かれています。

おわりに

新たなUIコンポーネントライブラリThemesを紹介しました。playgroundやThemePanelなどスタイリングに関するDXがとても良いところが印象的でした。
後発のライブラリですので、これまでのUIコンポーネントライブラリやPrimitivesを開発して来たプラクティスが生かされていますし、RSC対応もちゃんとされています。
さらに、既存のUIコンポーネントライブラリの多くが採用しているemotionを利用していないのでサーバー側でのレンダリングにおけるパフォーマンス上の問題も生じません。

このようなところから、これからのUIコンポーネントライブラリとして台頭してくると考えています。
UIコンポーネントライブラリを新しく選定する機会がありましたらぜひ採用したいと思いました。皆さんも採用を検討してみてはいかがでしょうか。

24
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?