倒數第二天了,來做個比較大的:嘗試復刻出 MUI StyleProvider 的效果。
兩套樣式設定存放在專案資料夾的 src/styles
中,分別是 dark 與 light。而 StyleProvider
與 StyleToggle
搭配後,實現的效果為「當使用者透過 StyleToggle
切換網站樣式後,StyleProvider
要負責將對應的樣式套用到自己的 children node 上」。
實作放在 src/model/style
中,透過 class Style
建立一個 Style
實例時,init()
會把指定路徑的樣式保存到 stylePool
中,並且實例也提供 getStyle()
來根據傳入的名稱(以今天的範例而言就是 light
與 dark
)回傳對應的設定。
而 export const StyleContext = createStyleContext<StyleKeys>();
則是負責建立樣式的 context。建立起來的 StyleContext
會被 StyleProvider
與 StyleToggle
引用,分別負責「提供樣式」與「根據使用者的操作,更新樣式名稱(進而連帶更新 StyleProvider
要傳遞 dark/light 哪一套樣式給 children node)」。
在元件 StyleProvider
中,透過 useEffect
來監聽 StyleToggle
是否有修改 styleName
,若有則根據新名稱套用對應的樣式。
實作在 StyleToggle
元件中,當使用者點擊 InputSwitch
元件時,觸發 handleToggleStyle
來切換 context?.styleName
,連帶影響 StyleProvider
提供的樣式,進而使專案套用上 dark/light 樣式設定。
元件中的 useSystemColorScheme
會在明天介紹,這個 hook
做的事情是「回傳系統的樣式設定」。讓 StyleToggle 也負責監聽此參數的理由是「讓專案可以根據使用者的系統深淺色設定,顯示對應的樣式」。
想調整樣式名稱(不想使用 dark/light
)的話,修改 STYLE_KEYS
陣列中的內容。
最初在設計元件時沒有考慮到與 StyleProvider 的搭配,有點遺憾今天的展示只能先簡單做出 dark/light mode 效果。自製元件或許不難,但要讓組成前端畫面的「樣式」與「元件」可以互相搭配,沒有仔細規劃獨立作業還是不太容易做到的 ?