」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 我如何為我的 React Native 專案設定設計系統以加快開發速度

我如何為我的 React Native 專案設定設計系統以加快開發速度

發佈於2024-11-08
瀏覽:717

曾经构建过您不想自己使用的应用程序吗?

当我还是初级应用程序开发人员时,我曾经构建混乱的用户界面。

有时,当看到这些 UI 时,我曾经想“世界上谁会想使用这个?它看起来很糟糕”。

其他时候,只是有些“不对劲的地方”我无法指出。

虽然我曾经从设计团队那里获得过令人惊叹的精美设计,但我的应用程序看起来连 20% 都没有那么好。

我意识到了这个问题,为了解决这个问题,我深入研究了这个问题,其中我发现了一个设计系统的概念,它改变了我构建应用程序的方式。

设计系统这个神奇的东西是什么?

理解设计系统是什么至关重要,这样才能理解我们为什么需要它。

设计系统基本上是您和您的团队设计决策的集中事实来源。它告诉您要使用什么颜色以及在哪里使用?该应用程序将有多少种类型的按钮?您列表中的卡片会有阴影吗?所有的答案都来自于设计系统。

以下是拥有设计系统的一些好处:

  • 一致的用户界面:您的界面不会无缘无故地到处出现那些奇怪的间隙。它在所有设备上的外观和感觉都是统一的。

  • 快速决策:设计系统强制执行一组特定的约束,以使您的决策更容易,而不是更困难。你拥有的选择越多,你遇到的分析瘫痪就越多。

  • 可扩展的应用程序:随着应用程序的发展,设计系统有助于重用组件,而不是从头开始构建。

  • 专注开发:您不再需要强调按钮应该是绿色还是蓝色。相反,您将专注于重要的事情。

工具和库

虽然有大量的 React Native UI 库,但我使用自定义方法,因为我在其中大多数库的性能和错误方面都有过可怕的经历。

我的方法唯一依赖的库是react-native-size-matters。

现在,在您尖叫“尺寸并不重要!”之前,让我向您保证它确实重要。尤其是在移动应用程序方面。

您不希望您的用户打开您的应用程序,看到一个覆盖所有内容的巨大徽标,并在删除之前思考“丑陋的是什么......”,甚至不尝试就删除,因为您的徽标隐藏了按钮。

这就是react-native-size-matters 可以发挥作用的地方。它通过缩放组件以适应设备来使您的应用程序具有响应能力。因此,无论用户使用哪种设备,您的徽标都会准确地保留在您放置的位置。

设置主题

我定义的第一件事是我的核心设计标记。这些是我的设计系统的构建模块。其中包括调色板、版式、间距和字体大小。

我通过使用以下代码创建 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 快速设计它的样式(如果您使用打字稿,则提供建议),如下所示:

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

这是我如何创建 Typography 组件的示例,我使用它来代替 React Native 的 Text 组件:


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';
import theme from './theme';

export const ThemeContext = createContext(theme);

export default function ThemeProvider({children}: PropsWithChildren) {
  return (
    {children}
  );
}


然后,在我的应用程序组件内:


export default function App() {
  return (
    
  );
}


现在我的整个应用程序都可以访问 ThemeContext,我创建了 useTheme 挂钩:


import {useContext} from 'react';
import {ThemeContext} from '../styles/theme/ThemeProvider';

export default function useTheme() {
  const theme = useContext(ThemeContext);
  return theme;
}


现在我可以通过调用 useTheme 挂钩在任何地方访问我的主题,如下所示:


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


深色模式

为了实现深色模式,在 theme.ts 文件中,我添加了另一个包含深色模式颜色的调色板。


export const darkTheme = {
  // define dark mode colors here keeping the keys same as the light mode only changing the values.
}


然后,在 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?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 機器學習中的 C++:逃離 Python 與 GIL
    機器學習中的 C++:逃離 Python 與 GIL
    介紹 當 Python 的全域解釋器鎖定 (GIL) 成為需要高並發或原始效能的機器學習應用程式的瓶頸時,C 提供了一個引人注目的替代方案。這篇部落格文章探討如何利用 C 語言進行 ML,並專注於效能、並發性以及與 Python 的整合。 閱讀完整的部落格! ...
    程式設計 發佈於2024-11-08
  • 如何使用 PHP 和 MySQL 以印地語儲存和顯示 Unicode 字串?
    如何使用 PHP 和 MySQL 以印地語儲存和顯示 Unicode 字串?
    使用PHP 和MySQL 儲存和顯示Unicode 字串(हिन्दी)嘗試儲存和顯示Unicode 字串時,您可能會遇到挑戰,特別是在印地語等語言中,由於編碼問題。為了解決這些問題,必須在資料庫和 PHP 腳本中設定適當的字元編碼和排序規則。 資料庫配置對於 MySQL資料庫,將資料庫和資料表編碼...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中將 UTF-8 字元轉換為 ISO-8859-1 並返回?
    如何在 PHP 中將 UTF-8 字元轉換為 ISO-8859-1 並返回?
    將UTF-8 字元轉換為ISO-88591 並傳回PHP當使用使用不同編碼的多個腳本時,需要在字元集之間進行轉換。其中一種轉換涉及將 UTF-8 字元轉換為 ISO-88591,反之亦然。 儘管存在 utf_encode() 和 _decode(),但將 UTF-8 直接轉換為 ISO-88591 ...
    程式設計 發佈於2024-11-08
  • 以下是一些標題選項,使用問題格式,重點關注文章中提出的挑戰和解決方案:

選項 1(直接且簡潔):
* 如何避免 Angul 中的模板標籤衝突
    以下是一些標題選項,使用問題格式,重點關注文章中提出的挑戰和解決方案: 選項 1(直接且簡潔): * 如何避免 Angul 中的模板標籤衝突
    為AngularJS 和Django 定制模板標籤由於模板標籤衝突,將AngularJS 與Django 集成可能會帶來挑戰,兩者都使用{{}}。為了克服這個問題,需要調整 AngularJS 或 Django 的模板標籤語法。 AngularJS 範本標籤自訂:在 AngularJS 1.0 中,...
    程式設計 發佈於2024-11-08
  • 每個開發人員都應該了解的高階 JavaScript 概念
    每個開發人員都應該了解的高階 JavaScript 概念
    JavaScript 是许多开发人员日常使用的语言,但其生态系统中存在许多隐藏的瑰宝,即使是经验丰富的开发人员也可能不熟悉。本文探讨了一些鲜为人知的 JavaScript 概念,它们可以显着提高您的编程技能。我们将介绍 代理、符号、生成器等概念,通过示例演示每个概念并解决问题以说明其强大功能。 最...
    程式設計 發佈於2024-11-08
  • 直接用mysqli_函數取代mysql_函數會帶來挑戰嗎?
    直接用mysqli_函數取代mysql_函數會帶來挑戰嗎?
    盲目地用 mysqli_ 取代 mysql_ 函數會導致問題嗎? 將程式碼庫更新到 PHP 7 需要將已棄用的 mysql_ 函數替換為 mysqli_ 對應函數。然而,一個常見的誤解是您可以直接進行全面替換。 答案:不,事情沒那麼簡單雖然函數名稱可能會出現類似地,與 mysql_ 相比,mysql...
    程式設計 發佈於2024-11-08
  • 為什麼 `malloc()` 在 C++ 中會導致「無效轉換」錯誤?
    為什麼 `malloc()` 在 C++ 中會導致「無效轉換」錯誤?
    Malloc 分配問題:了解「無效轉換」錯誤提供的程式碼在嘗試使用malloc 分配記憶體時引入了一個常見問題( )。此錯誤源自於將 malloc() 的回傳值直接指派給 char 指標而沒有進行正確的轉換。 malloc() 函數在堆中保留一塊記憶體並傳回一個通用的 void 指標。但是,程式碼將...
    程式設計 發佈於2024-11-08
  • 如何在 Zend Framework 中確定客戶端的時區?
    如何在 Zend Framework 中確定客戶端的時區?
    客戶端時區確定確定客戶端時區對於時間敏感的應用程式至關重要。這個問題探討如何在 Zend Framework 中取得此資訊。 以秒偏移量形式檢索時區取得時區的首選方法是作為 UTC 的秒數。例如,俄羅斯莫斯科將返回 36060,而英國倫敦將返回 0。 建議的解決方案建議的解決方案涉及利用jQuery...
    程式設計 發佈於2024-11-08
  • 如何使用 React 建立通知功能
    如何使用 React 建立通知功能
    Hello everyone ?? In today's tutorial, we'll guide you through building a real-time notifications feature using SuperViz, a powerful platform for rea...
    程式設計 發佈於2024-11-08
  • 了解命令式程式設計和聲明式程式設計之間的區別
    了解命令式程式設計和聲明式程式設計之間的區別
    當我剛開始學習React時,我的老師說:「JavaScript是命令式編程,而React是聲明式編程。」然而,一開始這對我來說不太有意義。因此,我決定將其分解以更好地理解其中的差異。 將命令式和聲明式程式設計與披薩進行比較? 為了更容易理解,讓我們來比較一下這兩種烹飪方法。 ...
    程式設計 發佈於2024-11-08
  • 如何使用 JPA 和 Hibernate 以 UTC 格式儲存日期/時間和時間戳記?
    如何使用 JPA 和 Hibernate 以 UTC 格式儲存日期/時間和時間戳記?
    使用JPA 和Hibernate 以UTC 格式儲存日期/時間和時間戳在Java Persistence API (JPA) 和Hibernate 中,管理日期/時間不同時區的時間戳值可能是一個挑戰。為了確保 UTC(協調世界時)時間的一致儲存和檢索,正確配置框架至關重要。 考慮提供的附註解的 JP...
    程式設計 發佈於2024-11-08
  • java.lang.RuntimeException 和 java.lang.Exception 之間的主要區別是什麼?
    java.lang.RuntimeException 和 java.lang.Exception 之間的主要區別是什麼?
    揭示java.lang.RuntimeException 和java.lang.Exception 的獨特本質在Java 異常領域內,兩個經常遇到的異常類別出現:java.lang.RuntimeException 和java.lang.Exception。為了有效地理解異常處理的複雜性,剖析它們之...
    程式設計 發佈於2024-11-08
  • 為什麼嵌入框陰影在透明背景的圖片上消失?
    為什麼嵌入框陰影在透明背景的圖片上消失?
    了解圖像上的插入框陰影問題在網頁設計中,使用插入框陰影在元素內創建深度和尺寸是一種常見技術。然而,在處理包含圖像的容器時,事情並不總是那麼簡單。當嵌入框陰影似乎在嵌入影像上消失時,就會出現問題。 隱形陰影的情況考慮原始問題中提供的範例:body { background-color: #0000...
    程式設計 發佈於2024-11-08
  • 如何在 ReactJS 中維護懸停狀態:解決事件註冊問題
    如何在 ReactJS 中維護懸停狀態:解決事件註冊問題
    在ReactJS 中維護懸停狀態:解決事件註冊問題使用內聯樣式時,您會遇到ReactJS 中懸停和活動事件的問題,因為onMouseEnter 和onMouseLeave 方法被證明是不可靠的。 要解決此問題,請考慮使用下列事件處理程序之一:onMouseDownonMouseEnter onMou...
    程式設計 發佈於2024-11-08
  • 如何在 JavaScript 中準確檢查 Null 值和空字串?
    如何在 JavaScript 中準確檢查 Null 值和空字串?
    檢查 JavaScript 中的 Null 值在 JavaScript 中,確定值是否為 null 有時會令人困惑。為了提供更深入的理解,本文將深入研究在 JavaScript 情境中偵測空值的細節。 檢查空值提供的程式碼片段旨在檢查跨多個變數的null 值:if (pass == null || ...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3