
Utility FirstになったNativeBase 3.0でスマホアプリのオリジナルUIコンポーネントを実装してみる
オリジナルのUIコンポーネントの実装はデザイン制作から必要になるなどハードルが高い作業ですが、NativeBase 3.0からサポートされたUtility Propsを活用するとこんな風に素早く実装を進めることができます。
スマホアプリの設定画面UIをNativeBaseで実装してみた
スマホアプリに良くある「設定画面」のUI。セクションごとに設定リストが表示されて、タイトルや設定の説明テキストをを表示できます。今回はこのリストをNativebase 3.0を使って実装してみます。
UIライブラリに良くあるコンポーネントではあるのですが、U-motion(※文末を参照ください)では使い方がわかりやすいようにヘルプ・テキストを表示していて、この機能が足りなかったためコンポーネントまるごとオリジナルで設計しています。
この記事ではNativeBase 3.0を対象にしていますが、NativeBaseのStyle PropsはStyled Systemを利用しているので、RebassのようなStyled Systemを使ったReact Native/Reactのライブラリ(あるいはStyled Systemと互換性のあるChakra-UI)でも応用できると思います。
VStackで縦方向=行のレイアウトを設定する
このリストUIのセクション内は下記の図のように3つのパートに分かれています。
そこで縦方向にコンポーネントをレイアウトするためのNativeBaseコンポーネント「VStack」を利用します。
const Section = ({ title, children, description }: SectionProps) => {
return (
<VStack space={4}>
{title && (
<HStack paddingX={4}>
<Text fontSize="md" bold color="gray.500">
{title}
</Text>
</HStack>
)}
<VStack borderRadius={10} backgroundColor="white">
{children}
</VStack>
{description && (
<HStack paddingX={4}>
<Text fontSize="sm" bold color="gray.400">
{description}
</Text>
</HStack>
)}
</VStack>
);
};
VStackは子要素を縦方向にレイアウトしてくれるコンテナ・ウィジェットです。「space」プロパティーを使ってコンテナ内の子要素の間隔を調整します。
HStackで横方向=カラムのレイアウトを設定する
今度はそれぞれの行要素内の子要素=カラムのレイアウトを指定していきます。
これは個別の設定項目を表示するコンポーネントです。一見複雑ですが、分解してみると小さなコンポーネントを横方向にレイアウトしていることがわかります。
HStack を使って横方向に子要素を配置していきます。実際のコードはこちらです。
const Item = ({ title, right, description, arrow = true }: ItemProps) => {
return (
<HStack
paddingLeft={4}
paddingRight={0}
paddingY={5}
alignItems="center"
justifyContent="space-between">
<VStack space={2}>
{title && (
<Text fontSize="md" bold color="black">
{title}
</Text>
)}
{description && (
<Text fontSize="md" bold color="gray.400">
{description}
</Text>
)}
</VStack>
<HStack justifyContent="flex-end" space={0} paddingRight={4}>
{typeof right === 'string' ? (
<Text alignSelf="center" numberOfLines={2}>
{right}
</Text>
) : (
right
)}
{arrow && (
<Icon
alignSelf="center"
size="sm"
as={<Ionicons name="arrow-forward" />}
textAlign="right"
/>
)}
</HStack>
</HStack>
);
};
Justify Contentで子要素の横方向の配置ポリシーを決定
リストの行全体をラップする HStack に justifyContent="space-between" を設定することでタイトルと右側の矢印のコンポーネントを均等に行全体に配置しています。
Justify Contentはこのように横方向に複数のコンポーネントが並ぶ場合の配置ポリシーを指定でき、このほかに左寄せ、中心揃え、右寄せなどのルールがあります。
Align Itemsで縦方向のレイアウトを決定
横一列に高さの異なる複数のコンポーネントを並べる場合、行のなかでの縦方向の位置も調整が必要になります。ボトム揃え、トップ揃え、中心揃えなどがありますが、今回は alignItems="center" を指定することで「中心揃え」で表示しています。
アイテム3ではタイトルの下にサブ・テキストが表示されてカラムの高さが他の行と異なっていますが、行全体として中央揃えになっているので違和感なく表示されています。サイズの異なるテキストや矢印のアイコンなどを綺麗に並べる場合はこの指定が便利です。
Paddingで見た目を整える
最後に要素ごとにpaddingを追加して見た目を整えます。
なお親要素のコンテナのspaceプロパティーで間隔を調整できるように、子要素はmarginを持たないようにします。
まとめ: タテとヨコのレイアウトの組み合わせが分かればだいたいのUIを自前で組むことができる
Justify ContentやAlign Itemsなどの名前をみてCSSのFlexレイアウト・システムを思い出した方も多いと思います。実際のところこれはFlexレイアウトです。HStackやVStackはFlexを適用したコンテナですね(NativeBaseの開発者はSwiftUIから影響を受けたと言っていました)。
今回ご紹介した縦方向のレイアウトと横方向のレイアウト、それにパディングがあれば実はだいたいのUIが実装できてしまいます。React NativeやHTML5のFlexレイアウトを駆使すればよいわけですが、NativeBaseはよく使うHStack、VStackなどをコンポーネント化ことで、ちょっとしたパラメータの追加で簡単にオリジナルUIを構築できる環境を提供してくれています。
NativeBase(Styled System)でUIを自由自在に組み立てることができるようになると、スマホ(とウェブ)のアプリ開発がだいぶ楽しくなってくるのでは?
みなさんも、ぜひ試してみてください🐮
・・・
おまけ: U-motion開発部はテクノロジーで農家さんに貢献したいエンジニアを募集中です!!
デザミス株式会社では、JavaScript/Reactでフロントエンド開発をしたいエンジニアと、バックエンド・エンジニアを募集中です。
こちらからお気軽に問い合わせてください。面接は無しでまずはカジュアル面談から、という方も大歓迎です。
フロントエンド
・React + TypeScriptを使った大規模なアプリケーション開発
・React Nativeを使ったネイティブ・アプリケーション開発
バックエンド
・大量のデータを扱うバックエンド開発(Rails、Python、AWS)
はじめてこのブログを読んだ方へ: U-motionとは?
U-motionは牛の首につけたセンサーを使って活動内容を記録、AIの力で健康状態を解析して畜産農家さんをサポートするモニタリング・システムです。
🐮