20251023
Radix UI
UIコンポーネントのライブラリ。
ヘッドレスな Radix Primitives と デフォルトスタイルが適用された Radix Themes がある。
Radix UI では他にもアイコンセットやカラーセットなども提供している。Radix UI Primitives が提供するのは機能のみのヘッドレスUI。
スタイルを自由にカスタマイズできる。
shadcn/ui は内部で Radix UI Primitives を使用している。各コンポーネントはWAI-ARIAのガイドラインに準拠したアクセシビリティを備えているため、ユーザーはスタイルをつけるだけでいい。全てのコンポーネントをインストールする必要はなく、必要なものだけインストールすることも可能。
全てのコンポーネントをインストールしたとしても適切にツリーシェイキングされるためバンドルが肥大することはない。
ブログ
Radix Primitives を使ってページネーションを実装する。
# 全部インストール
npm install radix-ui@latest// components/PaginationSelect/index.tsx
export default function PaginationSelect({maxPageNum, currentPage}: Props) {
const router = useRouter();
const onChangePage = (value: string) => {
router.replace(value === "1" ? `/blog` : `/blog/page/${value}`);
};
const items = Array.from({length: maxPageNum}).map((v, i) => (
<Select.Item key={String(i+1)} value={String(i+1)} className=" h-7 w-16 flex items-center justify-center relative rounded-sm text-center data-highlighted:bg-blue-100 data-highlighted:text-blue-600 dark:data-highlighted:bg-gray-600 dark:data-highlighted:text-white">
<div><Select.ItemText>{String(i+1)}</Select.ItemText></div>
<Select.ItemIndicator className="absolute left-1">
<CheckIcon />
</Select.ItemIndicator>
</Select.Item>
));
return (
<Select.Root defaultValue={String(currentPage)} onValueChange={onChangePage}>
<Select.Trigger className="mx-auto h-8 flex items-center bg-gray-100 dark:bg-gray-800 rounded-md px-1">
<div className="px-3">
<Select.Value />
</div>
<Select.Icon>
<ChevronDownIcon />
</Select.Icon>
</Select.Trigger>
<Select.Portal>
<Select.Content className="bg-white dark:bg-gray-900 rounded-sm border-1 border-gray-300 dark:border-gray-500 shadow-md">
<Select.ScrollUpButton className="flex items-center justify-center h-5">
<ChevronUpIcon />
</Select.ScrollUpButton>
<Select.Viewport className="p-1">
{items}
</Select.Viewport>
<Select.ScrollDownButton className="flex items-center justify-center h-5">
<ChevronDownIcon />
</Select.ScrollDownButton>
</Select.Content>
</Select.Portal>
</Select.Root>
)
}Selectの各サブコンポーネントが何を表しているかを理解するのに苦戦した。
公式サイトのサンプルコードと開発者ツールの実DOMを見比べながらなんとかスタイルを適用したものの、本当にこれでいいの?という不安が残る。
今冷静に見ると無駄にdivを使ってたりするのでこれは消せそう。