本系列文章會在筆者的部落格繼續連載!Design System 101 感謝大家的閱讀!
在 Button 這個系列篇章,我們介紹到了許多先前所提到的觀念,接著來做一個簡單的回顧
第一步: 將 Material Design 中所有的 Reference Token 與 System Token 以 json 的格式匯整到 @ui/design-token裡,並透過 Style Dictionary 產生 CSS 檔
第二步: 建立專門存放 Component Token 以及 Style 的專案 @ui/css,這樣的好處是當今天我們想要換框架時,不需要再重新寫一次 Style,並且不管遷移到任何框架,都可以保持樣式的一致性。
第三步: 核心組件的建立,例如前面章節所提到的 FocusScope
, FocusRing
又或是 Slots
這些都是其他組件的基底,而這部通常是最花時間的,但只要基底打好,當建立其他組件時就可以產生飛輪效應。
第四步: 建立共用組件,可能會像是 Button
, Badge
, Modal
又或是 Carousel
等等的組件,這些會層列在第一線處理各種使用者交互與體驗的場景。
接著讓我們回到 Button 組件的實作吧!
這是整個 Button 組件的關係圖,也是我們在前幾篇提到的
@ui/focus-ring
: 讓鍵盤使用者可以透過 focus ring 看到當前被 focus 的組件,而不影響滑鼠使用者。@ui/ripple
: 處理點擊按鈕時會出現的波浪紋動畫。@ui/slots
: 減少 props 的傳遞,可以透過 <SlotsProvider>
將想客製化的元素傳入。@ui/css
: 處理 Button 組件的 Component Token 以及各種交互時的樣式。ui
|-- packages
| |-- components
| | |-- button <---|
| | |-- focus-ring -|
| | |-- ripple -|
| | |-- slots -|
| |-- css
| | |-- button
@ui/focus-ring
(範例程式碼)@ui/ripple
: 處理點擊按鈕時會出現的波浪紋動畫。(範例程式碼)@ui/slots
: 減少 props 的傳遞,可以透過 <SlotsProvider>
將想客製化的元素傳入。(範例程式碼)@ui/css
: 處理 Button 組件的 Component Token 以及各種交互時的樣式。(範例程式碼)最後則是將所有套件引入到 <Button />
當中
export const Button = React.forwardRef((props, forwardRef) => {
props = useSlotProps(props, 'button');
const { variant, children, isDisabled } = props;
const btnRef = useRef(null);
const ref = useComposeRef(forwardRef, btnRef);
return (
<FocusRing isDisabled={isDisabled}>
<button
{...props}
className={clsx('tocino-Button', { 'is-disabled': isDisabled })}
data-variant={variant}
ref={ref}
>
<span className="tocino-Button__label">{children}</span>
<Ripple target={btnRef} />
</button>
</FocusRing>
);
});
所呈現出來的結果
這是 Button 組件大致的實作,當然還有很多細節因為時間的關係沒有辦法一一調整,但希望能夠幫助到大家!