「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > 開発を迅速化するために React Native プロジェクトのデザイン システムをセットアップする方法

開発を迅速化するために React Native プロジェクトのデザイン システムをセットアップする方法

2024 年 11 月 8 日に公開
ブラウズ:304

自分では使いたくないアプリを作成したことがありますか?

私がジュニア アプリ開発者だった頃、混沌としたユーザー インターフェイスを構築していました。

これらの UI を見て、「一体誰がこれを使いたいと思うでしょうか? 見た目はひどいです。」と時々思っていました。

また、指摘できない「何かがおかしい」こともありました。

以前はデザイン チームから驚くほど洗練されたデザインを提供してもらいましたが、アプリの見た目は 20% も良くありませんでした。

私はこの問題を認識しており、それを解決するためにウサギの穴のような研究を進め、アプリの構築方法を変えるデザイン システムの概念に出会いました。

デザインシステムと呼ばれるこの素晴らしいものは何ですか?

なぜデザイン システムが必要なのかを理解するには、デザイン システムとは何なのかを理解することが重要です。

デザイン システムは基本的に、あなたとあなたのチームのデザイン決定のための一元的な情報源です。どの色をどこで使用するかがわかります。アプリには何種類のボタンがありますか?リスト内のカードには影がありますか?すべての答えはデザイン システムから得られます。

デザイン システムを導入するメリットの一部を次に示します:

  • 一貫した UI: インターフェイスには、理由もなくあちこちに奇妙なギャップが存在することはありません。すべてのデバイスで見た目も感触も統一されます。

  • 迅速な意思決定: デザイン システムでは、意思決定を難しくするのではなく、より簡単にするために、特定の制約セットが強制されます。選択肢が多ければ多いほど、より多くの分析麻痺に遭遇します。

  • スケーラブルなアプリ: アプリが成長するにつれて、デザイン システムは、最初から構築するのではなく、コンポーネントの再利用に役立ちます。

  • 開発に集中: ボタンを緑にするか青にするかを強調する必要はもうありません。代わりに、重要なことに集中します。

ツールとライブラリ

React Native UI ライブラリはたくさんありますが、そのほとんどでパフォーマンスとバグに関してひどい経験をしたため、私はカスタム アプローチを使用しています。

私のアプローチで私が依存している唯一のライブラリは、react-native-size-matters です。

「サイズなんて関係ない!」と叫ぶ前に、重要だということを保証させてください。特にモバイル アプリに関してはそうです。

ユーザーがアプリを開いて、すべてを覆う巨大なロゴを見て、ロゴがボタンを隠していたために何も試さずに削除してしまう前に、「なんて醜いんだろう…」と思ってほしくないでしょう。

そこで、react-native-size-matters が役に立ちます。デバイスに合わせてコンポーネントをスケーリングすることで、アプリの応答性が向上します。したがって、ユーザーがどのデバイスを持っていても、ロゴは配置した場所に正確に残ります。

テーマを設定する

私が最初に定義するものの 1 つは、コア デザイン トークンです。これらは私のデザイン システムの構成要素です。これらには、カラー パレット、タイポグラフィ、間隔、フォント サイズが含まれます。

これを行うには、次のコードを使用して theme.ts ファイルを作成します。


import {moderateScale} from 'react-native-size-matters';

// after installing custom fonts:
export const FontFamily = {
  bold: 'Poppins-Bold',
  semibold: 'Poppins-SemiBold',
  medium: 'Poppins-Medium',
  regular: 'Poppins-Regular',
  thin: 'Poppins-Thin',
};

const colors = {
  primary100: '#2E2C5F',
  primary80: '#524DA0',
  primary60: '#736DDF',
  primary40: '#A09BFF',
  primary20: '#DCDAFF',

  secondary100: '#484A22',
  secondary80: '#858945',
  secondary60: '#D9DF6D',
  secondary40: '#F8FCA1',
  secondary20: '#FDFFD4',

  neutral100: '#131218',
  neutral90: '#1D1C25',
  neutral80: '#272631',
  neutral70: '#343341',
  neutral60: '#3E3D4D',
  neutral50: '#53526A',
  neutral40: '#757494',
  neutral30: '#9C9AC1',
  neutral20: '#CBC9EF',
  neutral10: '#E8E7FF',
  white: '#fff',
  black: '#222',

  error: '#E7002A',
  success: '#3EC55F',
  warning: '#FECB2F',
  info: '#157EFB',
};

const theme = {
  colors,
  fontSizes: {
    xxl: moderateScale(32),
    xl: moderateScale(28),
    lg: moderateScale(24),
    md: moderateScale(20),
    body: moderateScale(17),
    sm: moderateScale(14),
    xs: moderateScale(12),
    xxs: moderateScale(10),
    xxxs: moderateScale(8),
  },
  spacing: {
    none: 0,
    xxs: moderateScale(4),
    xs: moderateScale(8),
    md: moderateScale(12),
    lg: moderateScale(16),
    xl: moderateScale(20),
    xxl: moderateScale(24),
    xxxl: moderateScale(28),
  },
};

export default theme;


再利用可能なコンポーネントの作成

デザイン トークンを配置したら、ボックス、タイポグラフィ、入力などの再利用可能なコンポーネントをいくつか定義します。これらのコンポーネントはデザイン トークンに準拠し、アプリ全体での一貫性を確保します。

たとえば、Box コンポーネントの作成方法は次のとおりです:


import {
  View,
  type ViewProps,
  type FlexAlignType,
  type ViewStyle,
} from 'react-native';
import theme from '../styles/theme/theme';

export interface IBox extends ViewProps {
  backgroundColor?: keyof typeof theme.colors;
  p?: keyof typeof theme.spacing;
  pv?: keyof typeof theme.spacing;
  ph?: keyof typeof theme.spacing;
  pt?: keyof typeof theme.spacing;
  pb?: keyof typeof theme.spacing;
  pl?: keyof typeof theme.spacing;
  pr?: keyof typeof theme.spacing;
  m?: keyof typeof theme.spacing;
  mv?: keyof typeof theme.spacing;
  mh?: keyof typeof theme.spacing;
  mt?: keyof typeof theme.spacing;
  mb?: keyof typeof theme.spacing;
  ml?: keyof typeof theme.spacing;
  mr?: keyof typeof theme.spacing;
  gap?: number;
  flex?: number;
  flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
  alignItems?: FlexAlignType;
  justifyContent?:
    | 'center'
    | 'flex-start'
    | 'flex-end'
    | 'space-between'
    | 'space-around'
    | 'space-evenly';
  rounded?: boolean;
}

export default function Box({
  backgroundColor,
  p,
  pv,
  ph,
  pt,
  pb,
  pr,
  pl,
  m,
  mv,
  mh,
  mt,
  mb,
  ml,
  mr,
  children,
  style,
  flex,
  alignItems,
  justifyContent,
  flexDirection = 'column',
  rounded = false,
  gap = undefined,
  ...rest
}: IBox) {
  const getMargin = () => {
    const obj: any = {};

    if (m) {
      obj.margin = theme.spacing[m];
      return obj;
    }
    if (mt) obj.marginTop = mt ? theme.spacing[mt] : 0;
    if (mb) obj.marginBottom = mb ? theme.spacing[mb] : 0;
    if (ml) obj.marginLeft = ml ? theme.spacing[ml] : 0;
    if (mr) obj.marginRight = mr ? theme.spacing[mr] : 0;
    if (mv) obj.marginVertical = theme.spacing[mv];
    if (mh) obj.marginHorizontal = theme.spacing[mh];
    return obj;
  };

  const getPadding = () => {
    const obj: any = {};

    if (p) {
      obj.padding = theme.spacing[p];
      return obj;
    }

    if (pt) obj.paddingTop = pt ? theme.spacing[pt] : 0;
    if (pb) obj.paddingBottom = pb ? theme.spacing[pb] : 0;
    if (pl) obj.paddingLeft = pl ? theme.spacing[pl] : 0;
    if (pr) obj.paddingRight = pr ? theme.spacing[pr] : 0;
    if (pv) obj.paddingVertical = theme.spacing[pv];
    if (ph) obj.paddingHorizontal = theme.spacing[ph];

    return obj;
  };

  const boxStyles: ViewStyle[] = [
    {
      backgroundColor: backgroundColor
        ? theme.colors[backgroundColor]
        : undefined,
      flex,
      justifyContent,
      alignItems,
      flexDirection,
      borderRadius: rounded ? 10 : 0,
      gap,
    },
    getMargin(),
    getPadding(),
    style,
  ];

  return (
    
      {children}
    
  );
}


この新しく作成した Box コンポーネントを View の代わりに使用します。これにより、次のように props を通じてすばやくスタイルを設定できます (また、typescript を使用している場合は提案を提供します)。

How I set up Design System for my React Native Projects for  Faster Development

これは、React Native の Text コンポーネントの代わりに使用する Typography コンポーネントを作成する方法の例です:

「react」から React をインポートします。 import {Text, type TextProps} from 'react-native'; テーマ、{FontFamily} を '../styles/theme/theme' からインポートします。 エクスポート インターフェイス ITypography は TextProps を拡張します { サイズ?: テーマのタイプのキー、フォントサイズ; color?: テーマのタイプのキー。色; textAlign?: '中央' | '自動' | '左' | '右' | 「正当化する」; バリアント?: FontFamily のタイプのキー; } デフォルト関数のエクスポート タイポグラフィ({ サイズ、 色、 textAlign、 子供たち、 スタイル、 変異体、 ...休む }: Iタイポグラフィ) { 戻る ( {子供たち} テキスト> ); }

import React from 'react';
import {Text, type TextProps} from 'react-native';
import theme, {FontFamily} from '../styles/theme/theme';

export interface ITypography extends TextProps {
  size?: keyof typeof theme.fontSizes;
  color?: keyof typeof theme.colors;
  textAlign?: 'center' | 'auto' | 'left' | 'right' | 'justify';
  variant?: keyof typeof FontFamily;
}

export default function Typography({
  size,
  color,
  textAlign,
  children,
  style,
  variant,
  ...rest
}: ITypography) {
  return (
    
      {children}
    
  );
}


カスタム タイポグラフィ コンポーネントにスタイルをいかに迅速に追加できるかをプレビューします:

How I set up Design System for my React Native Projects for  Faster Development

カスタム使用テーマフック

テーマを何度もインポートする代わりに、アプリ内の任意の場所で呼び出すカスタム useTheme フックを作成してコードを読みやすくし、テーマに準拠したスタイルを追加します。

これを行うために、React の Context API を利用してテーマをアプリに渡します。

ThemeProvider.tsx ファイルを作成し、その中にアプリ コンポーネントをラップする ThemeContext と ThemeProvider を定義します。コードは次のとおりです:

import React、{type PropsWithChildren、createContext} from 'react'; './theme' からテーマをインポートします。 エクスポート const ThemeContext = createContext(テーマ); デフォルト関数のエクスポート ThemeProvider({children}: PropsWithChildren) { 戻る ( {children} ); }

import React from 'react';
import {Text, type TextProps} from 'react-native';
import theme, {FontFamily} from '../styles/theme/theme';

export interface ITypography extends TextProps {
  size?: keyof typeof theme.fontSizes;
  color?: keyof typeof theme.colors;
  textAlign?: 'center' | 'auto' | 'left' | 'right' | 'justify';
  variant?: keyof typeof FontFamily;
}

export default function Typography({
  size,
  color,
  textAlign,
  children,
  style,
  variant,
  ...rest
}: ITypography) {
  return (
    
      {children}
    
  );
}


次に、アプリ コンポーネント内:

デフォルト関数 App() をエクスポート { 戻る ( テーマプロバイダ> ); }

import React from 'react';
import {Text, type TextProps} from 'react-native';
import theme, {FontFamily} from '../styles/theme/theme';

export interface ITypography extends TextProps {
  size?: keyof typeof theme.fontSizes;
  color?: keyof typeof theme.colors;
  textAlign?: 'center' | 'auto' | 'left' | 'right' | 'justify';
  variant?: keyof typeof FontFamily;
}

export default function Typography({
  size,
  color,
  textAlign,
  children,
  style,
  variant,
  ...rest
}: ITypography) {
  return (
    
      {children}
    
  );
}


アプリ全体が ThemeContext にアクセスできるようになったので、useTheme フックを作成します。

'react' から {useContext} をインポートします。 {ThemeContext} を '../styles/theme/ThemeProvider' からインポートします。 デフォルト関数 useTheme() をエクスポート { const テーマ = useContext(ThemeContext); テーマを返す。 }

import React from 'react';
import {Text, type TextProps} from 'react-native';
import theme, {FontFamily} from '../styles/theme/theme';

export interface ITypography extends TextProps {
  size?: keyof typeof theme.fontSizes;
  color?: keyof typeof theme.colors;
  textAlign?: 'center' | 'auto' | 'left' | 'right' | 'justify';
  variant?: keyof typeof FontFamily;
}

export default function Typography({
  size,
  color,
  textAlign,
  children,
  style,
  variant,
  ...rest
}: ITypography) {
  return (
    
      {children}
    
  );
}


これで、次のように useTheme フックを呼び出すことで、どこからでもテーマにアクセスできるようになります。

const テーマ = useTheme(); // 使用例: テーマ.カラー.プライマリー100; テーマ.spacing.md; テーマ.fontSizes.lg;

const theme = useTheme();
// example usage:
theme.colors.primary100;
theme.spacing.md;
theme.fontSizes.lg;


ダークモード

ダーク モードを実装するには、theme.ts ファイルに、ダーク モード用の色を含む別のカラー パレットを追加します。

エクスポート const darkTheme = { // ここでダーク モードの色を定義します。キーはライト モードと同じに保ち、値のみを変更します。 }

import React from 'react';
import {Text, type TextProps} from 'react-native';
import theme, {FontFamily} from '../styles/theme/theme';

export interface ITypography extends TextProps {
  size?: keyof typeof theme.fontSizes;
  color?: keyof typeof theme.colors;
  textAlign?: 'center' | 'auto' | 'left' | 'right' | 'justify';
  variant?: keyof typeof FontFamily;
}

export default function Typography({
  size,
  color,
  textAlign,
  children,
  style,
  variant,
  ...rest
}: ITypography) {
  return (
    
      {children}
    
  );
}


次に、ThemeProvider でユーザー設定を確認し、次のようにテーマを切り替えます。


import {useColorScheme} from 'react-native';

export default function ThemeProvider({children}: PropsWithChildren) {
const isDarkMode = useColorScheme() === 'dark';
return (
{children}
);
}



結論

この明確に構造化されたアプローチに従うことで、アプリに必要な明瞭さ、一貫性、美しさがもたらされ、同時にデザイン上の決定にこだわる必要がなくなったため、開発速度が少なくとも 10 倍速くなりました。

このアプローチを試してみて、コメントで意見を聞かせてください。少しは改善できるかも知れませんね?

リリースステートメント この記事は次の場所に転載されています: https://dev.to/msaadullah/how-i-set-up-design-system-for-my-react-native-projects-for-10x-faster-development-1k8g?1If there何らかの侵害がある場合は、削除するには[email protected]までご連絡ください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3