iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
Modern Web

關於 UI 元件你所該知道的事系列 第 21

Day 21 - 實戰演練 — Button / ButtonGroup / IconButton

https://ithelp.ithome.com.tw/upload/images/20211006/20120754ZEa98ucQ95.png

從今天起到結賽都會是實戰演練的環節了!

接下來的日子真槍實彈、彈無虛發,帶大家從理論走向實踐,把一些基本的元件實作出來吧!

這篇章會怎麼實作?

老樣子我的風格是不會直接開始上 Code ,貼心如我當然是要來先帶大家理解一下整個實作流程啦!

那主要就是以下四大步驟,分別會對應到的是 Interface/TS、HTML、CSS、JS/React!

  1. 根據需求跟設計稿來實作 Interface
    • 元件的 API 該怎麼開、使用元件的開發者能怎麼用,以 React 來說就是 元件有哪些 Props
    • 這個階段也會多多去參考其他 UI 元件庫開了哪些 API 以及如何命名的。
  2. 實作架構 — 組織元件會用到的 HTML Element
  3. 排版與美化元件 — 撰寫 Tailwind CSS(許多樣式也會跟 Props 有依賴性,像是 Color )
  4. 元件的各種狀態與自身的互動邏輯 — JS 跟 React ( onClick 和 Portal 之類的 )

這邊如同四大天王總是會有五個人的定律,這裡其實也是有第五點(或是說第零點),那就是 Day 29 會介紹到的單元測試,之所以有可能是第零點的原因是走 TDD(測試驅動開發)的流程,但我並之前沒走過 TDD 的流程,而詳細做測試的幾種方法我都會在 Day 29 跟大家好好說明清楚,並補上一些小 Demo !

在知道怎麼去實作一個元件後,這篇章介紹的重點會放在 InterfaceJS / React 的處理上,HTML 和 CSS 因為通常挺直覺的,因此有遇到特殊情況的時候才會提,如果好奇的話可以再去看 Github Source Code,而測試就更不用說,並不是這系列的重點,而且逐篇介紹也會有點冗長,就先集中到 Day 29 再說吧!

前言講完了,那就事不宜遲開始吧!

Button

想先看 Code 或是 Demo 的由此去

Github Repo: ithelp-ui-demo

Live Demo:Button

Interface / API

一樣先介紹一下它的介面會包含什麼:

https://ithelp.ithome.com.tw/upload/images/20211006/20120754p6uXFD5jdo.png

在往後實作 Interface 都有一個重要的概念:

先繼承原生 HTMLElement 的 Props 再來擴充需要的 Props!

https://ithelp.ithome.com.tw/upload/images/20211006/20120754dDUBIoxmH9.png

到這邊可能會有人問 Hover 的 onMouseEnter 和 onMouseLeave 的情況怎麼處理?

這時候就可以來觀念釐清一下了,現在前端開發已經將元件根據功能切得挺細的,因此作為一個 UI 元件的 Button 功能就要很純粹,他該做的事情就是被點擊然後觸發對應的行為。

至於提供 Hover 顯示資訊這個功能的 UI 元件是 Tooltip,若是有更多客製化的需求可能比較適合手刻客製化,而不是去無限擴張 Button 這個 UI 元件,導致最後元件複雜到難以使用。

但當然,這是我參考的 Ant 、 Material 和個人開發經驗的想法 ,實際上如果系統有很頻繁地需要讓 Button 在 hover 時多做點事的話,那放進去也是沒有問題的,重點還是團隊協作者或是讓要使用 Button 的開發者能有一個共識。

元件實作

在 Button 的元件實作這邊,可以看到主要都是在把 Props 轉換成可以使用的 Tailwind Utility Class,主要是使用在 Typography 有講到的鍵值對比對 和 簡易的三元判斷來實作。

比較值得看的就是在 prefix Icon 、 suffix Icon 和 loading 的處理了。

https://ithelp.ithome.com.tw/upload/images/20211006/20120754bSIQBLTwUX.png

至此就完成 Button 的實作啦!

完整的程式碼我有放在 Github Repo: ithelp-ui-demo

一樣有做一個 Storybook Live Demo(待補) ,可以讓大家玩玩看不同的 Props 變化:

https://ithelp.ithome.com.tw/upload/images/20211006/20120754t9qD6escok.png

另外也展示了一下其他的情境:

https://ithelp.ithome.com.tw/upload/images/20211006/20120754bWa8x0osWe.png

Button 講完後順便大放送把 IconButton 和 ButtonGroup 的實作講一下!

IconButton

顧名思義就是把 Button 封裝成可以單一 Icon 的形式。

https://ithelp.ithome.com.tw/upload/images/20211006/20120754unPm0UcRV6.png

https://ithelp.ithome.com.tw/upload/images/20211006/20120754p2Bhrglbyc.png

Usage

<IconButton variant="outlined" size="small">
  <Icon icon={PlusIcon} />
</IconButton>

ButtonGroup

在 ButtonGroup 就沒有 IconButton 這麼單純了,但基本上也只是在把原本的 ButtonProps 整合在一統一給到其下的子 Button 們。

而新增的 Props 主要就 attached、spacing 和 orientation 三個:

https://ithelp.ithome.com.tw/upload/images/20211006/201207541wnQrCskGR.png

介面實作

https://ithelp.ithome.com.tw/upload/images/20211006/20120754jhcVDlZ37I.png

元件實作

這邊比較需要注意的是用到 React.cloneElement 的概念,這個 API 是 React 讓我們能複製傳進來的 Children 用的。

會需要的原因是要統一管理子 Button 們,因此是把 Props 統一後再 Clone 時再賦予一次,這樣的話不管使用者在 ButtonGroup 底下給了 Button 哪些重複的屬性,都能夠被 ButtonGroup 這邊洗掉而以 ButtonGroup 給的值來呈現。

https://ithelp.ithome.com.tw/upload/images/20211006/201207540qrtY5B3gI.png

小結

第一篇的元件實作完成!可能一次塞得有點多東西希望讀者們不會消化不良,也可以先存著等到之後要實作 Button 時在來看,程式碼的部份就不講太多細節,主要會以補充的方式來跟大家說實作過程中需要注意的點,若還是有不懂或是寫錯的地方就再麻煩各位讀著們幫忙抓錯了!


上一篇
Day 20 - UML x Component — Independent (下)
下一篇
Day 22 - 實戰演練 — Portal 系列
系列文
關於 UI 元件你所該知道的事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言