Material UI v4 版本發布 🎉
React 組件,讓網頁開發更快更簡單。建立您自己的設計系統,或從 Material Design 開始。
Material UI v4 終於到來。我們對這次發布感到非常興奮,因為它為 UI 組件定義了更好的基礎。感謝大家,特別是 團隊,以及所有貢獻程式碼、問題分類和支援的人。感謝您們。
✨✨✨ 請參閱 GitHub 上的 4.0.0 版本發行說明。✨✨✨
https://mui.dev.org.tw/
摘要
v4 的高階目標
Material UI v1 在一年前 發布。版本 4 是自那時以來我們最重要的主要版本發布。對於那些不熟悉專案歷史的人來說,我們沒有發布 v2,而 v3 僅引入了輕微的瀏覽器支援變更。
這次發布發生在我們的 固定頻率發布策略中。我們嘗試至少每 12 個月發布一個主要版本,最多每 6 個月發布一次。從 v0 到 v1 的遷移很痛苦,幾乎感覺像在使用兩個不同的 UI 庫。我們已盡力將從 v3 遷移到 v4 所需的時間降到最低。為了幫助簡化過渡,您可以遵循此遷移指南 📚。它不應超過幾個小時。
此版本受到兩個主要因素的影響。首先,在三月份進行的開發人員調查之後,我們分析了結果,並使用它們來更改未來一年的優先事項。其次,我們需要跟上 React 社群和 Material Design 規範的最新最佳實踐。
自訂
Google 的 Material Design 團隊已將其設計系統框架的自訂功能作為核心功能:Material Theming。這對我們來說是該庫的一個重要面向。自 v1 發布以來,我們一直在改進組件自訂示範,一次又一次的發布。我們展示了各種不同的設計
在聽取了數百位開發人員的 v3 自訂體驗後,我們意識到我們可以做得更好。我們發現了 4 類常見問題。
- CSS 權重。開發人員的樣式權重需要更高,才能勝過 Material UI 注入到頁面中的樣式。預設情況下,Material UI 將其樣式注入到
<head>
元素的末尾。但是,styled components 和其他流行的樣式解決方案會在它之前注入樣式,從而失去權重。為了解決這個問題,我們引入了一個新的 prop:injectFirst
。
import { StylesProvider } from '@mui/styles';
<StylesProvider injectFirst>
{/* Your component tree.
Styled components can override Material UI's styles. */}
</StylesProvider>;
使用 injectFirst 後的 DOM 輸出。
- classes 樣板程式碼。在 v1 努力的早期,我們決定使用 CSS-in-JS 樣式解決方案:JSS。絕大多數 CSS-in-JS 解決方案輸出非確定性的類別名稱,例如
.fHmkjM
。此設計決策有助於隔離每個組件的樣式,但是,它使覆蓋更困難。我們在 v1 中引入了classes
API,以將所有元素作為緩解此問題的嘗試。我們已經觀察了幾個月對此 API 的使用,並看到許多人在使用它時遇到困難。將類別名稱應用於正確的元素可能具有挑戰性,並且也需要樣板程式碼。為了進一步改善這種情況,我們已將類別名稱生成更改為輸出全域類別名稱,同時保持classes
API 像以前一樣工作 💅。
並排比較有效的類別與全域方法。
⚠️ 使用全域類別名稱提供更多功能,但也伴隨著責任。我們鼓勵增加自訂樣式隔離的模式。
- 虛擬類別。 虛擬類別是添加到選擇器中的關鍵字,用於指定所選元素的特殊狀態。原生元素支援各種虛擬類別,最受歡迎的類別是:
:focus
、:hover
、:active
。有時,Material UI 無法使用虛擬類別,因為平台中不存在該狀態,例如選單項目的選取狀態。Material UI 實作了對八種不同自訂虛擬類別的支援。重要的是要了解,使用虛擬類別時需要增加權重。例如
.MenuItem {
color: black;
}
/* We increase the specificity */
.MenuItem.Mui-selected {
color: blue;
}
- 動態變化。 作為最受歡迎的功能之一,我們新增了對樣式函式的支援
const useStyles = makeStyles({
// style rule
foo: (props) => ({
backgroundColor: props.backgroundColor,
}),
bar: {
// CSS property
color: (props) => props.color,
},
});
function MyComponent() {
// Simulated props for the purpose of the example
const props = {
backgroundColor: 'black',
color: 'white',
};
// Pass the props as the first argument of useStyles()
const classes = useStyles(props);
return <div className={`${classes.foo} ${classes.bar}`} />;
}
文件
文件在開發人員調查中被報告為第三個最關鍵的痛點。我們已修復了一些報告的問題,並旨在繼續改進。
- TypeScript。TypeScript 的成長令人印象深刻,他們的文件網站的流量在 3 年內增長了 6 倍。Material UI v1 隨附了內建的 TypeScript 定義,但我們需要做更多的事情。Sebastian 領導了將所有示範從 JavaScript 遷移到 TypeScript 的工作。這有兩個重要的含義。首先,我們對示範進行類型檢查,這大大提高了我們的 TypeScript 測試覆蓋率。我們在遷移過程中修復了許多問題。其次,如果您正在使用 TypeScript 編寫您的應用程式,您可以直接複製和貼上我們的示範,而無需轉換它們,或修復晦澀的錯誤。
https://typescript.dev.org.tw 隨時間推移的流量估計。
使用 JS/TS 切換開關以查看 JavaScript 或 TypeScript 中的程式碼
i18n。開發人員從世界各地來到 Material UI 的文件。我們希望盡可能多地包含人們 🌎🌍🌏。我們完成了在 v3 中開始的工作,方法是研究 Algolia 搜尋支援、Google 搜尋索引、目錄和側邊導航基礎架構。
我們要感謝 Danica Shen、Dominik Engel 和 Jairon Alves Lima 在 🇨🇳、🇩🇪 和 🇧🇷 翻譯方面所做的英勇工作,同時也不忘其他 348 位(並且還在增長)翻譯人員。
最佳實踐。我們現在建議在盡可能的情況下使用 hooks API 而不是 classes API。我們已遷移了大部分示範,以展示單一方法。
更好的 UX。我們已更改選單組織,以將所有組件分組在單個導航項目下。我們已將背景顏色更改為白色,以增加文字對比度和可讀性。
效能
您可能會擔心使用 Material UI 的組件會使您的網站/應用程式臃腫並減慢速度。您自己編寫組件會更好嗎?嗯,我們的使命是盡可能降低這種成本 🚀。
- Tree shaking。Material UI v4 是第一個支援使用 ES 模組進行原生 tree shaking 的版本。這有一個重要的 DX 優勢——您現在可以在導入多個組件時使用解構式導入
import {
Table
TableBody,
TableCell,
TableHead,
TableRow,
Paper,
} from '@mui/material';
- 套件大小縮減。套件大小從最後一個 v3 版本到第一個 v4 beta 版本之間,從 95 kB gzipped 降至 80 kB gzipped 以下。考慮到我們沿途新增了新功能和組件 😍!這是通過許多小的增量更改實現的:tree shaking、刪除 多個 內部 依賴項、hooks 遷移、clsx 遷移、智慧 Babel 外掛程式 等。
套件大小減少 -15%。⚠️ 請不要使用絕對數字來比較不同的 UI 庫。沒有人應該導入整個 barrel index.js 檔案。重要的是您導入的單個模組的成本。
- 持續追蹤套件大小。套件大小的縮減只有在我們在每個 pull request 中追蹤此指標時才有可能。我們改進了我們的策略,從 size-limit 轉變為 React 啟發的解決方案。
精細級別追蹤
- Preact X。 我們引入了一個與 Preact 的工作 整合範例。Preact 是一個快速、體積小 1/10 的 React 替代方案,具有相同的現代 API。我們將盡力支援它。
- 執行時期效能。我們聽說有些人在使用 Material UI 的執行時期成本方面遇到困難。我們解決了一些報告的問題,但沒有系統地解決。我們觀察到通過從 classes API 轉移到 hooks API 略有提升。但是,由於我們缺乏正確設置的效能基準,因此很難取得進展。這是 v5 需要考慮的事情。
為未來做準備
Material UI v4 依賴於 React ≥16.8.0。這是第一個支援 新的 Hooks API 的 React 版本。
- Ref 轉發。大多數時候,您使用
ref
prop 來存取 React 元素的底層 DOM 節點。您可能想要聚焦元素、計算元素的位置等等。您永遠不需要存取 Material UI 組件的實例方法,它們被認為是私有的。當真正需要時,組件會公開一個action
。例如,您可能希望在 tab 指示器位置與 tab 項目位置不同步時更新它。為了簡化這種使用情境,Sebastian 領導了一項工作,以實作React.forwardRef()
。實際上,這意味著您可以像使用內建組件(button
、div
等)一樣檢索對 DOM 節點的引用。
import { Button } from '@mui/material';
function MyButton() {
const myRef = React.useRef();
return <Button ref={myRef}>;
}
Hooks 遷移。雖然 沒有計劃 從 React 中移除 classes,但 React 團隊 鼓勵 使用 hooks API 編寫新程式碼。Josh 領導了一項工作,以使用 hooks API 重寫我們絕大多數的組件。此變更有幾個優點。
並非所有 我們支援的平台 都可以原生使用 class API,因此我們使用 Babel 轉換語法。函數在任何地方都受到支援,它們需要的程式碼行數更少。我們觀察到通過消除轉換 classes 的需要,gzipped 套件大小減少了 -2%。
它減少了 React Dev Tools ⚛️ 中的雜訊,因為我們可以將最常見情況下的中間元素數量從 5 個減少到 2 個。我們發現 hooks API 更容易使用:編寫、閱讀和更改。這對每個人的生產力都有淨正面影響。開發人員閱讀我們的原始碼以尋找靈感,因此我們應該盡力推廣最佳模式。
生產環境中一個 Typography 元素的 React Dev Tools 輸出(這個 POC 可能會進一步改善情況)。
並行模式。React 分享了其 發布時間表,說明即將進入 React 的重要功能。並行模式 應在未來幾個月內發布。並行模式允許 React 應用程式通過在不阻塞主線程的情況下呈現組件樹來提高響應速度。我們一直在努力為其做好準備。大部分工作與修復 <React.StrictMode> 警告有關。您應該很快就能利用它 🔥。
淺層測試。 我們已刪除我們內部的大部分淺層測試,以依賴 完整掛載測試。
Material Design
我們的大多數用戶對我們組件的美觀實用方面感興趣,而不是嚴格應用 Material Design 指南。但是,我們認為對於我們來說,跟上指南的更新很重要。自 Google 在 Google I/O 2018 上將其作為應用程式的設計語言以來,該規範進行了最重要的更新。
當我們發布 Material UI v1 時,Material Design “v2” 的公告讓我們感到驚訝。從那時起,我們一直在努力升級我們的組件。在 v4 中,我們更新了 Tab、Snackbar、Checkboxes、Radios、Switches、List、Dialog 和其他組件的樣式 ✨。
Dense Outlined 文字欄位
Dense Filled 文字欄位
新功能?
有太多新事物,我們無法詳盡列舉。除了我們已經宣布的內容外,您還會發現
眾多範例之一
Box 組件的應用範例。
新間距助手 API 的範例。
- 由 Dmitriy Kovalenko 📅 建立和支援的新 @material-ui/pickers 套件。
鍵盤支援
內嵌模式
- 新的 @mui/styles 套件,可隔離我們的樣式解決方案。它可以獨立於核心組件使用。它帶有一個 hooks API,需要的樣板程式碼更少 😍
import * as React from 'react';
import { makeStyles } from '@mui/material/styles';
const useStyles = makeStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
export default function Hook() {
const classes = useStyles();
return <button className={classes.root}>Hook</button>;
}
⚠️ 請注意 @mui/styles 和 @mui/material/styles 之間的差異。後者包含預設主題。
- @mui/styles 的良好支援 Gatsby 外掛程式。
- 由 Packt 出版並由 Adam Boduch 編寫的Cookbook。
下一步?
我們共同完成了我們在一年前在 v1 版本 部落格文章 中定義的大部分目標。我們為每位貢獻者感到自豪。我們將嘗試以相同的規律性執行這些新目標
- 更多組件。 到目前為止,這是該庫最受歡迎的改進方面。我們已經確定了一些我們有興趣建置的有用組件
- 版面配置組件
- Autocomplete/ ComboBox / Dropdown List / MultiSelect
- 核心中的滑桿和對範圍值的支援
- 樹狀檢視
- Dropzone / 上傳
- 骨架畫面
- 巨幕
- 輪播
- 評分
- 時間軸
- 進階表格
請告訴我們您想要的組件!🚀
- 文件。文件至關重要。我們正在開發頁面排名機制,這將幫助我們更好地確定我們在文件方面的工作優先順序。
- 在核心中使用
system
。 我們收到了關於新 system 套件的良好回饋。展望未來,我們將嘗試將其移至核心組件。理想情況下,您應該能夠使用主題中的動態顏色和變體,以及存取所有 props
import { Button } from '@mui/material';
<Button mt={{ xs: 2, md: 3 }}>Hello worlds</Button>;
- Styled components。 我們已經看到許多人要求遷移到 styled components。我們希望 Material UI v5 能夠更好地與社群最受歡迎的工具保持一致,但同時,我們也不想破壞您的程式碼。因此,我們將致力於將組件與樣式解決方案隔離。新的 @mui/styles 套件是朝這個方向邁出的第一步。我們設想一個您可以使用 Material UI 的世界,其樣式使用 styled components、linaria 和 JSS,或者不使用任何樣式。開發人員應該能夠使用他們首選的樣式解決方案,而無需支付兩個 CSS-in-JS 運行時的成本。
- 無障礙功能。 雖然我們盡力修復用戶報告的所有無障礙功能問題,但我們認為我們可以做得更好。我們希望對我們所有的組件 ♿️ 進行專業的 ADA 審核。
高級主題商店
我們將如何維持這個雄心勃勃的路線圖?我們將遵循 Bootstrap 模型。我們正在開發 高級主題商店。
我們已與生態系統中最好的主題作者建立了合作夥伴關係。在幾週內,您應該會找到最好的 Material UI 範本和主題的集合 😍。
感謝您
最後,再次感謝每一位為 Material UI v4 做出貢獻的人。我對這次發布感到非常興奮!這僅僅是個開始。我們將繼續努力交付最佳的 React UI 框架組件。
您可以在 Medium 上找到相同的文章。