淺談數棧產品裡的 Descriptions 元件

袋鼠云数栈前端發表於2024-09-27

我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式資料中臺產品。我們始終保持工匠精神,探索前端道路,為社群積累並傳播經驗價值。

本文作者:修能

What's?

數棧產品裡的 Descriptions 元件實際上就是 antd 的 Descriptions 元件,那麼 antd 的 Descriptions 元件是什麼?

在數棧產品中,我們通常使用的方式是 bordered + small 的模式。

即:

<Descriptions bordered size="small">
  <Descriptions.Item label="任務名稱">
    {taskName}
  </Descriptions.Item>
  <Descriptions.Item label="指標表名稱">
    {tableName}
  </Descriptions.Item>
</Descriptions>

展示如下:

file

平平無奇,甚至非常普通。但,這裡面暗藏玄機。

Why?

file

我們要實現一行只有一個 Item 的設計方式。這裡我們可以藉助 Descriptions 元件的 column API 實現。

 - <Descriptions bordered size="small">
 + <Descriptions bordered size="small" column={1}>

file

此時,一位靚仔發出疑惑:“怎麼就這麼寬了?”

file

那麼,直接根據設計稿的尺寸給設定寬度吧

contentStyle={{
  width: 630,
}}
labelStyle={{
  width: 140,
}}

file

可以?不可以!由於我們這個模組是在詳情的抽屜裡,抽屜的寬度是不固定的,那麼這裡設定固定值會導致有問題!……有問題吧?

file

這裡的 label 寬度並沒有按照所設定的來,而是自適應的撐滿了。

但是,都是自適應,這裡的自適應並不是我們想要的,根據 UI 設計師的確認,這裡的自適應應該是 label 的大小不變,content 的大小自適應。


怎麼實現?

設定 contentStyle 的 width 為 'calc(100% - 140px)'

---

file

看起來,這個需求搞定了?實際上,還有問題!

這裡,我們需要模擬一下任務名稱很長並且用 Button 元件的情況。

file

這裡,我們想到,可以用 EllipsisText 元件解決溢位省略的問題。

file

糟糕,貌似並沒有生效,這是為何?


分析原因如下:

這裡我們一下原因,首先,我們這裡的省略邏輯是如下

  1. 透過設定 maxWidth 為百分比(不能設定具體數值,為何?),然後配合 overflow

file

我們從 DOM 樹上可以看出來,理論上,我們應該是 td 元素的寬度百分比,同時 td 元素設定的寬度也是百分比,所以理論上是 tr 元素的百分比。


這裡我們發現,tr 元素的寬度並沒有按照我們設想的是繼承父元素的寬度,而是被子元素撐開了。那麼,我們嘗試在 tr 上增加 width:100% 使其寬度為繼承父元素的寬度。

file

還是無效,這是為何?


我們這裡注意到,width 是需要繼承父元素的寬度,而父元素的寬度也是被撐開的。這裡我們省略一些定位的過程,快進到定位 table 元素。

這個 Descriptions 元件的根元素是 table 元素。table 元素相比起普通的 div 元素來說,更加複雜,其相關的 CSS 屬性更加難以捉摸。


觀察到,這裡的 table 元件上有如下屬性

file

table 的寬度被設定了 100%,但是並沒有繼承父元素的寬度,而是被子元素撐開了。

這裡我們注意到 table 有一條屬性為 table-layout,在 MDN 中該屬性的定義為:

table-layout CSS 屬性定義了用於佈局表格的單元格、行和列的演算法。

如果設定為 auto,則表示

預設情況下,大多數瀏覽器使用自動錶格佈局演算法。表格及其單元格的寬度會根據內容自動調整大小。


到這裡就破案了,如果設定為了 auto,則單元格會根據內容自適應,那麼就會導致父元素(即單元格)會被子元素的寬度撐開,即使給父元素的寬度設定了一個固定值也會失效。

如果表格佈局是 auto,表格將會根據其內容自動擴充套件大小,而不考慮指定的 width

file

那麼,可以確認,如果我們想要用 Descriptions 元件實現文案的省略,則不可避免地需要將 table-layout 設定為 fixed 屬性。

How

然而,Descriptions 元件預設的 table-layout 是為 auto,且並沒有相關的屬性去修改這個值。

所以這裡我們只能透過全域性的 CSS 去修改?(theme 可做)

但這裡,我選擇在指標裡重寫 Descriptions 元件,讓使用者可控地去使用 Descriptions 元件。


題外話,需要插入說明一下,如果 table-layout 設定為 auto,且單元格的內容並沒有溢位,即一開始設定的那樣子。那麼此時單元格的寬度其實並非我們設定的值,而是基於我們給不同單元格設定的 width 計算出的比例進行等比放大或縮小。

例如:我現在給單元格分別設定 140px 和 280px。

此時若 table 寬度恰好為 420px,則 label(即 th 元素)恰好為 140px,content(即 td 元素)恰好為 280px。

若 table 寬度大於 420px,則按照 1:2 的方式等比放大。

file

file

此時 table 的寬度為:

file

計算可得:806 * 1/3 ≈ 248。

最後

歡迎關注【袋鼠雲數棧UED團隊】~
袋鼠雲數棧 UED 團隊持續為廣大開發者分享技術成果,相繼參與開源了歡迎 star

  • 大資料分散式任務排程系統——Taier
  • 輕量級的 Web IDE UI 框架——Molecule
  • 針對大資料領域的 SQL Parser 專案——dt-sql-parser
  • 袋鼠雲數棧前端團隊程式碼評審工程實踐文件——code-review-practices
  • 一個速度更快、配置更靈活、使用更簡單的模組打包器——ko
  • 一個針對 antd 的元件測試工具庫——ant-design-testing

相關文章