在過去的幾篇文章中,我們探討了如何使用 CSS Modules 和 CSS 變數 來優化應用中的主題切換機制,並提高應用的靈活性和可維護性。今天,我們基於Figma 設計稿中介紹頁去設計一個靈活的按鈕元件,這個按鈕不僅支持多種狀態(例如正常、懸停、激活、禁用),還允許你自定義圖標的位置,並能夠在多國語言和主題切換的環境中保持一致的使用體驗。
按鈕是用戶與應用交互的重要界面元件,因此設計一個靈活且功能齊全的按鈕對整體 UI 的可用性至關重要。以下是我們的按鈕元件將支持的核心功能:
我們的按鈕元件可以通過以下屬性來靈活地控制樣式、圖標、大小和狀態:
屬性 | 說明 | 類型 | 預設值 |
---|---|---|---|
type |
設置按鈕樣式類型(primary 、secondary ) |
string | primary |
icon |
設置按鈕的圖標 | ReactNode | null |
iconPosition |
設置圖標的位置(left 、right 、top 、bottom ) |
string | left |
afterContent |
設置 ::after 的內容,通常用來顯示一些動態效果 |
string | "" |
size |
設置按鈕的大小(small 、medium 、large ) |
string | medium |
isLoading |
加載中狀態(顯示加載動畫) | boolean | false |
isDisabled |
禁用狀態,按鈕變灰且無法點擊 | boolean | false |
children |
按鈕的文本或內容 | ReactNode | null |
這些屬性讓我們的按鈕在設計上能夠靈活處理不同的使用場景,包括樣式控制、圖標設置、大小選擇、狀態切換等。
在 Light Mode 下,按鈕在各狀態的樣式變化如下圖所示:
prop-types
和react-icons
為了在開發過程中進行屬性檢查,我們將安裝 prop-types
來確保按鈕接收到正確的屬性類型。另外,我們還將使用 react-icons
來為按鈕添加圖標。打開終端並運行以下命令:
npm install prop-types
npm install react-icons --save
接下來,我們開始編寫按鈕元件,首先定義它的基本屬性和默認值。
//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
}) {
說明:
type
:這個屬性決定按鈕的樣式類型,例如 primary
表示主要按鈕,默認是 primary
。icon
和 iconPosition
:允許按鈕嵌入圖標,並提供圖標位置的選擇。icon 可以接受從 react-icons 庫中導入的圖標,例如:import { FaSave } from 'react-icons/fa'
;afterContent
:用來定義按鈕的 ::after
內容,通常用於動態效果。size
:按鈕大小控制,例如 small
、medium
或 large
。isLoading
和 isDisabled
:這兩個屬性用來控制按鈕的狀態,分別表示按鈕是否處於加載狀態或禁用狀態。我們接下來根據傳入的屬性來動態生成按鈕的樣式,確保按鈕在不同狀態下能應用正確的樣式。
// 動態設置按鈕的圖標位置
const buttonClasses = `
${styles.button}
${styles[type]}
${styles[size]}
${isDisabled ? styles.disabled : ''}
`;
這段代碼動態構建了按鈕的 CSS 類名。不同的 type
和 size
值會應用不同的樣式類別。當 isDisabled
為 true
時,按鈕將應用禁用樣式,使其無法點擊並變灰。
我們還需要為按鈕添加圖標功能,並根據圖標的位置來調整其顯示位置。
const iconClasses = `${styles.icon} ${styles[iconPosition]}`;
這裡,我們根據 iconPosition
的值來設置圖標的樣式類。圖標可以靈活地出現在按鈕的左側、右側、上方或下方。
這一部分是按鈕的主要 JSX 結構,根據 isLoading
、icon
等屬性進行動態渲染。
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>
);
說明:
disabled={isDisabled || isLoading}
:如果按鈕處於禁用狀態或正在加載,它將被禁用以防止用戶進行交互。loader
)。iconPosition
,圖標會動態渲染在按鈕的左側或右側。children
屬性傳遞進來。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<∕> ✨ 期待與你繼續探索更多技術知識!