はじめに
この記事は React Native Advent Calendar 14日目の記事です。
近年、Web界隈ではShadcn UIのような「コードを所有する(コピペ型)」スタイルが主流です。
私自身もTamaguiなど、既存の巨大UIライブラリの運用コストや破壊的変更に疲弊し、React Nativeでもこの体験を求めて出会ったのが BNA UI です。
今回はこのライブラリの紹介と、さらに痒い所に手が届くよう拡張したフォーク版 kota113/ui について紹介します。
BNA UI とは?
BNA UI は、クロスプラットフォームで、ミニマルでモダンなUIコンポーネント集です。
Shadcnのように、必要なコンポーネントのコードを自分のプロジェクトに取り込んで使用します。
過度な装飾がなく、デザインの土台として非常に優秀です。
ただベースがしっかりしており使いやすいのですが、実際にアプリに組み込んでいく中で、元のコンポーネントの不具合修正や機能拡張の必要が出てきました。
痒い所に手が届く拡張版
そこでオリジナルの良さを活かしつつ、DX(開発者体験)とUX(ユーザー体験)を向上させるために以下の機能を追加・修正しました。
主な変更点は以下の3つです。
1. XStack, YStack, ZStack の追加
レイアウトを組む際、毎回 flexDirection や alignItems を書くのはボイラープレートになりがちです。そこで、TamaguiやChakra UI, Swift UIのような直感的なレイアウトコンポーネントを追加しました。
- XStack: 横並び(Row)
- YStack: 縦並び(Column)
- ZStack: 重ね合わせ(Absolute positioning)
これにより、JSXの見通しが劇的に良くなります。
// Before: 普通のViewで書く場合
<View style={{ flexDirection: 'row', gap: 8, alignItems: 'center' }}>
<Icon name="user" />
<Text>ユーザー名</Text>
</View>
// After: XStackを使用
<XStack gap={8} items="center">
<Icon name="user" />
<Text>ユーザー名</Text>
</XStack>
2. ButtonのAndroidHaptics対応
オリジナルではiOSで触覚フィードバックがありましたが、Androidでは別のAPIを使用するためか未実装でした。
そこで、Android端末でもボタン押下時にHaptics(振動)が正しく動作するように修正を加えました。
3. BottomSheetの自動高さ調整
モーダルやメニューとしてよく使う BottomSheet ですが、中身のコンテンツ量に応じて高さを可変にしたいことはありませんか?
固定の高さやパーセンテージ指定だけだと、中身が少ない時に無駄な余白ができたり、逆に多すぎて見切れたりします。
そこで、中身の要素に応じた自動高さ調整オプションを追加しました。
<BottomSheet
snapPoints={`fit`} // `fit` を指定
>
<YStack padding={5}>
<Text>中身がこれだけでも...</Text>
<Button>ピッタリの高さになります</Button>
</YStack>
</BottomSheet>
動的なコンテンツを表示する際も、常に最適なサイズ感でシートを表示できるようになりました。
まとめ
BNA UI は、Shadcn UIのように「コードを所有する」アプローチで開発できる素晴らしいライブラリです。ブラックボックス化しないため、プロジェクトに合わせて汎用性を維持したままコンポーネントを整備できるのが魅力です。
ぜひ私が拡張した kota113/ui もチェックしてみてください!
IssueやPRもお待ちしています。