參考了 MUI Badge 的一些設計,最後決定實作成「當 props.badgeContent 的值為 falsity 時,不顯示 badge 點;並且使用者可以透過設定 props.variant = 'dot' 來渲染無內容的小型 bodge 點」。

套了一層 span 來處理定位問題就讓一切變得非常簡單了。首先透過 badgeWrapperStyle 來製造定位錨點,再來是 baseStyle 來讓 props.badgeContent 的內容可以水平垂直置中。而 standardStyle 與 dotStyle 分別對應 props.variant = 'standard' 與 props.variant = 'dot' 的樣式需求(大小點)。
再來與 Tooltip 的方向類似,根據 props.vertical 與 props.horizontal 來調整 badge 點位置。這部分可以參考 positionStyle 的邏輯。
最後為了讓使用者可以透過 props.badgeColor 與 props.badgeBgColor 快速定義 Badge 外觀,故將 colorStyle 也獨立出來,根據以上兩個 props 來調整回傳的樣式內容。
判斷邏輯如下。在使用者設定 props.variant === 'dot' 時必定顯示小型 badge 點,或當使用者有傳入非 falsity 的 props.badgeContent 時也會顯示「帶有 props.badgeContent 的 badge 點。而如果滿足條件 props.variant === 'standard' 且 props.badgeContent 為 falsity 時,隱藏整個 badge 點。
const renderBadge = useMemo(() => {
if (variant === 'dot') {
return (
<span className={cn(baseStyle, dotStyle, colorStyle, positionStyle)} />
);
}
if (badgeContent) {
return (
<span className={cn(baseStyle, standardStyle, colorStyle, positionStyle)}>
{badgeContent}
</span>
);
}
return <React.Fragment />;
}, [variant, badgeContent, colorStyle, positionStyle]);
需注意如果調整了 standardStyle 與 dotStyle 的 width/height 尺寸,記得確認 baseStyle 中的 border-radius 數值是否需一併更新,避免 badge 點形狀無法呈現(接近)圓形的外觀。
本次鐵人賽相對單純的定位系元件,雖然在最後段才登場,但如果想開始嘗試自行製作元件的話,算是一個相對簡單的起點。