iT邦幫忙

2024 iThome 鐵人賽

DAY 14
0
JavaScript

從PM到前端開發:我的React作品集之旅系列 第 14

Day 14 : 打造高效的 React 按鈕設計方案(上)

  • 分享至 

  • xImage
  •  

在過去的幾篇文章中,我們探討了如何使用 CSS Modules 和 CSS 變數 來優化應用中的主題切換機制,並提高應用的靈活性和可維護性。今天,我們基於Figma 設計稿中介紹頁去設計一個靈活的按鈕元件,這個按鈕不僅支持多種狀態(例如正常、懸停、激活、禁用),還允許你自定義圖標的位置,並能夠在多國語言和主題切換的環境中保持一致的使用體驗。

客製化按鈕的設計

按鈕是用戶與應用交互的重要界面元件,因此設計一個靈活且功能齊全的按鈕對整體 UI 的可用性至關重要。以下是我們的按鈕元件將支持的核心功能:

  • 靈活的圖標位置:允許用戶根據需求設置圖標顯示在按鈕的左側或右側。
  • 多國語言支持:按鈕文本可以根據當前語言環境動態調整。
  • 主題切換:按鈕樣式能夠根據應用的 Light ModeDark Mode 進行動態變化。

按鈕元件屬性表

我們的按鈕元件可以通過以下屬性來靈活地控制樣式、圖標、大小和狀態:

屬性 說明 類型 預設值
type 設置按鈕樣式類型(primarysecondary string primary
icon 設置按鈕的圖標 ReactNode null
iconPosition 設置圖標的位置(leftrighttopbottom string left
afterContent 設置 ::after 的內容,通常用來顯示一些動態效果 string ""
size 設置按鈕的大小(smallmediumlarge string medium
isLoading 加載中狀態(顯示加載動畫) boolean false
isDisabled 禁用狀態,按鈕變灰且無法點擊 boolean false
children 按鈕的文本或內容 ReactNode null

這些屬性讓我們的按鈕在設計上能夠靈活處理不同的使用場景,包括樣式控制、圖標設置、大小選擇、狀態切換等。

按鈕設計圖

在 Light Mode 下,按鈕在各狀態的樣式變化如下圖所示:
https://ithelp.ithome.com.tw/upload/images/20240913/20168330pNfIUr5Y7u.png

實際演練

Step 1: 安裝prop-typesreact-icons

為了在開發過程中進行屬性檢查,我們將安裝 prop-types 來確保按鈕接收到正確的屬性類型。另外,我們還將使用 react-icons 來為按鈕添加圖標。打開終端並運行以下命令:

npm install prop-types
npm install react-icons --save

Step 2: 設置基本屬性

接下來,我們開始編寫按鈕元件,首先定義它的基本屬性和默認值。

//src/components/buttons/button.jsx
import React from 'react';
import PropTypes from 'prop-types';
import * as styles from '@/components/buttons/Button.module.scss';

function Button({
    type = 'primary',
    icon,
    iconPosition = 'left',
    afterContent = '',
    size = 'medium',
    isLoading,
    isDisabled,
    children,
    ...props
}) {

說明:

  1. type:這個屬性決定按鈕的樣式類型,例如 primary 表示主要按鈕,默認是 primary
  2. iconiconPosition:允許按鈕嵌入圖標,並提供圖標位置的選擇。icon 可以接受從 react-icons 庫中導入的圖標,例如:import { FaSave } from 'react-icons/fa';
  3. afterContent:用來定義按鈕的 ::after 內容,通常用於動態效果。
  4. size:按鈕大小控制,例如 smallmediumlarge
  5. isLoadingisDisabled:這兩個屬性用來控制按鈕的狀態,分別表示按鈕是否處於加載狀態或禁用狀態。

Step 3: 動態生成按鈕的 CSS 類名

我們接下來根據傳入的屬性來動態生成按鈕的樣式,確保按鈕在不同狀態下能應用正確的樣式。

// 動態設置按鈕的圖標位置
    const buttonClasses = `
    ${styles.button} 
    ${styles[type]} 
    ${styles[size]} 
    ${isDisabled ? styles.disabled : ''}
  `;

這段代碼動態構建了按鈕的 CSS 類名。不同的 typesize 值會應用不同的樣式類別。當 isDisabledtrue 時,按鈕將應用禁用樣式,使其無法點擊並變灰。

Step 4:處理圖標與圖標位置

我們還需要為按鈕添加圖標功能,並根據圖標的位置來調整其顯示位置。


const iconClasses = `${styles.icon} ${styles[iconPosition]}`;

這裡,我們根據 iconPosition 的值來設置圖標的樣式類。圖標可以靈活地出現在按鈕的左側、右側、上方或下方。

Step 5:按鈕的核心結構

這一部分是按鈕的主要 JSX 結構,根據 isLoadingicon 等屬性進行動態渲染。

jsx
複製程式碼
return (
    <button
        className={buttonClasses}
        disabled={isDisabled || isLoading}
        style={{ '--after-content': `url(${afterContent})` }}
        {...props}
    >
        {isLoading ? <span className={styles.loader}></span> : null}

        {/* 根據 iconPosition 動態渲染圖標 */}
        {icon && iconPosition === 'left' && <span className={iconClasses}>{icon}</span>}

        {children} {/* 傳入按鈕文本 */}

        {icon && iconPosition === 'right' && <span className={iconClasses}>{icon}</span>}
    </button>
);

說明:

  1. disabled={isDisabled || isLoading}:如果按鈕處於禁用狀態或正在加載,它將被禁用以防止用戶進行交互。
  2. 加載動畫:如果按鈕正在加載,會顯示一個加載動畫 (loader)。
  3. 圖標渲染:根據 iconPosition,圖標會動態渲染在按鈕的左側或右側。
  4. 按鈕內容:按鈕的文本或其他內容通過 children 屬性傳遞進來。

Step 6: 使用prop-types 進行類型檢查

使用 prop-types 來檢查傳遞給按鈕元件的屬性類型,保證我們在開發過程中能夠傳遞正確的屬性值。例如,如果我們錯誤地傳遞了一個數字作為 children,而不是字串或 React 元素,prop-types 會發出警告,讓開發者及時修正錯誤。

Button.propTypes = {
    children: PropTypes.node.isRequired,
    type: PropTypes.oneOf(['primary', 'secondary']),
    icon: PropTypes.string,
    iconPosition: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),
    afterContent: PropTypes.string,
    size: PropTypes.oneOf(['small', 'medium', 'large']),
    isLoading: PropTypes.bool,
    isDisabled: PropTypes.bool,
};

結語

今天我們深入探討了如何設計一個靈活且高效的 React 按鈕元件,並通過多種屬性(如圖標位置、按鈕狀態、主題切換等)來滿足不同的應用場景需求。在下一篇文章中,我們將深入研究 Button.module.scss,進一步探討按鈕的樣式設計,並展示如何結合圖標、加載動畫和彈出提示框來構建更複雜的按鈕組合。

當設計一個按鈕時,你是否考慮過按鈕在不同狀態(如懸停、激活、禁用)下的視覺一致性?你如何確保按鈕在不同主題(如 Light Mode 和 Dark Mode)下保持良好的可讀性和用戶體驗?

在下一篇文章中,我們將帶著你一起體驗如何解決這些問題,通過實際操作來理解按鈕的最佳樣式設計。

完整按鈕元件程式碼已上傳至 GitHub,歡迎查看並實踐。
👉 前往 GitHub 的 Button.jsx 查看完整程式碼。


流光館Luma<∕> ✨ 期待與你繼續探索更多技術知識!



上一篇
Day 13: 告別 Sass map-get,用 CSS 變數簡化主題管理
下一篇
Day 15 : 打造高效的 React 按鈕設計方案(下)
系列文
從PM到前端開發:我的React作品集之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言