本文介紹Shoelace,一個由Cory LaViska創建的組件庫,但它與眾不同。它定義了所有標準的UX組件:標籤、模態框、手風琴、自動完成等等。這些組件開箱即用,美觀、易用且完全可定制。但它並非使用React、Solid或Svelte等框架創建這些組件,而是使用Web Components;這意味著您可以將它們與任何框架一起使用。
Web Components很棒,但目前還有一些小問題需要注意。
我之前說過它們可以在任何JavaScript框架中使用,但我之前也寫過,React對Web Components的支持目前很差。為了解決這個問題,Shoelace專門為React創建了包裝器。
另一個我個人比較喜歡的選擇是,創建一個輕量級的React組件,它接受Web組件的標籤名稱及其所有屬性,然後處理React的不足之處。我之前的一篇文章中討論過這個選項。我喜歡這個方案,因為它旨在被刪除。 React的實驗分支目前已經解決了Web組件互操作性問題,因此一旦發布,任何使用的輕量級Web組件互操作組件都可以被搜索和刪除,留下直接的Web組件用法,而無需任何React包裝器。
在撰寫本文時,對SSR的支持也很差。理論上,有一種叫做聲明式Shadow DOM (DSD) 的技術可以實現SSR。但是瀏覽器支持有限,而且DSD實際上需要服務器支持才能正常工作,這意味著Next、Remix或您在服務器上使用的任何其他工具都需要具備一些特殊處理能力。
也就是說,還有其他方法可以讓Web Components與使用Next等工具進行SSR的Web應用程序“正常工作”。簡而言之,註冊Web Components的腳本需要在解析標記之前運行在一個阻塞腳本中。但這將是另一篇文章的主題。
當然,如果您正在構建任何類型的客戶端渲染SPA,則這不是問題。這就是我們在這篇文章中將要使用的。
由於我希望這篇文章重點關注Shoelace及其Web組件特性,因此我將對所有內容使用Svelte。我還將使用這個Stackblitz項目進行演示。我們將一起逐步構建這個演示,但隨時都可以打開REPL查看最終結果。
我將向您展示如何使用Shoelace,更重要的是,如何自定義它。我們將討論Shadow DOM以及它們阻止哪些外部樣式(以及哪些樣式不被阻止)。我們還將討論::part
CSS選擇器——這可能對您來說是全新的——我們甚至會看到Shoelace如何允許我們覆蓋和自定義其各種動畫。
如果您在閱讀本文後發現自己喜歡Shoelace,並想在React項目中嘗試它,我的建議是使用我介紹中提到的包裝器。這將允許您使用Shoelace的任何組件,並且一旦React發布他們已經擁有的Web組件修復程序(在19版中查找),就可以完全刪除它。
Shoelace有相當詳細的安裝說明。最簡單的方法是將<script></script>
和<link>
標籤添加到您的HTML文檔中,就是這樣。但是,對於任何生產應用程序,您可能只想選擇性地導入所需的內容,並且也有相應的說明。
安裝Shoelace後,讓我們創建一個Svelte組件來渲染一些內容,然後逐步完成完全自定義它的步驟。為了選擇一些比較複雜的內容,我使用了標籤和對話框(通常稱為模態框)組件。以下是一些主要來自文檔的標記:
<sl-tab-group> <sl-tab panel="general" slot="nav">General</sl-tab> <sl-tab panel="custom" slot="nav">Custom</sl-tab> <sl-tab panel="advanced" slot="nav">Advanced</sl-tab> <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab> <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel> <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel> <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel> <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel> </sl-tab-group> <sl-dialog label="Dialog" no-header=""> Hello World! <sl-button> open = false}>Close</sl-button> </sl-dialog> <br><br> <button> open = true}>Open Dialog</button>
這將呈現一些漂亮且有樣式的標籤。活動標籤的下劃線甚至會很好地進行動畫處理,並從一個活動標籤滑動到下一個活動標籤。
我不會浪費您的時間來詳細介紹Shoelace網站上已經詳細記錄的每個API。相反,讓我們研究一下如何最好地交互和完全自定義這些Web Components。
調用Web組件上的方法和訂閱事件可能與您習慣使用的普通框架略有不同,但這並不太複雜。讓我們看看如何操作。
標籤組件(<sl-tab-group></sl-tab-group>
)有一個show
方法,該方法手動顯示特定標籤。為了調用它,我們需要訪問標籤的基礎DOM元素。在Svelte中,這意味著使用bind:this
。在React中,它將是一個ref。等等。由於我們使用的是Svelte,讓我們聲明一個標籤實例變量:
let tabs;
……並綁定它:
<sl-tab-group bind:this="{tabs}"></sl-tab-group>
現在我們可以添加一個按鈕來調用它:
<button on:click="{()"> tabs.show("custom")}>Show custom</button>
事件也是同樣的道理。當顯示新標籤時,會觸發一個sl-tab-show
事件。我們可以對我們的tabs
變量使用addEventListener
,或者可以使用Svelte的on:event-name
快捷方式。
<sl-tab-group bind:this="{tabs}" on:sl-tab-show="{e"> console.log(e)}></sl-tab-group>
這可以工作,並在顯示不同的標籤時記錄事件對象。
通常我們渲染標籤並讓用戶在它們之間點擊,因此這項工作通常甚至不需要,但如果您需要它,它就在那裡。現在讓我們使對話框組件具有交互性。
對話框組件(<sl-dialog></sl-dialog>
)接受一個open
屬性,該屬性控制對話框是否……打開。讓我們在我們的Svelte組件中聲明它:
<sl-tab-group> <sl-tab panel="general" slot="nav">General</sl-tab> <sl-tab panel="custom" slot="nav">Custom</sl-tab> <sl-tab panel="advanced" slot="nav">Advanced</sl-tab> <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab> <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel> <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel> <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel> <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel> </sl-tab-group> <sl-dialog label="Dialog" no-header=""> Hello World! <sl-button> open = false}>Close</sl-button> </sl-dialog> <br><br> <button> open = true}>Open Dialog</button>
它還有一個sl-hide
事件,用於隱藏對話框。讓我們傳遞我們的open
屬性並綁定到隱藏事件,以便當用戶點擊對話框內容外部將其關閉時,我們可以重置它。讓我們添加一個點擊處理程序到該關閉按鈕,以將我們的open
屬性設置為false,這也會關閉對話框。
let tabs;
最後,讓我們連接我們的打開對話框按鈕:
<sl-tab-group bind:this="{tabs}"></sl-tab-group>
就是這樣。與組件庫的API交互或多或少是直接的。如果這篇文章只做了這些,那就相當無聊了。
但是Shoelace——使用Web Components構建——意味著某些東西,特別是樣式,的工作方式會與我們習慣使用的略有不同。
在撰寫本文時,Shoelace仍處於測試階段,創建者正在考慮更改一些默認樣式,甚至可能完全刪除一些默認樣式,這樣它們就不會再覆蓋主機應用程序的樣式了。我們將介紹的概念無論如何都是相關的,但如果您使用它時,一些我提到的Shoelace細節有所不同,也不要感到驚訝。
Shoelace的默認樣式雖然很好,但我們的Web應用程序可能也有自己的設計,並且希望我們的UX組件與之匹配。讓我們看看如何在Web Components的世界中做到這一點。
我們不會試圖實際改進任何東西。 Shoelace的創建者比我更擅長設計。相反,我們只看看如何更改東西,這樣您就可以適應自己的Web應用程序。
在您的DevTools中查看其中一個標籤標題;它應該如下所示:
我們的標籤元素創建了一個帶有.tab
和.tab--active
類的div容器和一個tabindex
,同時還顯示了我們為該標籤輸入的文本。但請注意,它位於shadow root內。這允許Web組件作者向Web組件添加自己的標記,同時還提供一個放置我們提供的內容的地方。注意<slot></slot>
元素?這基本上意味著“將用戶在Web組件標籤之間渲染的任何內容放在這裡”。
因此<sl-tab></sl-tab>
組件創建一個shadow root,向其中添加一些內容以渲染漂亮樣式的標籤標題以及一個佔位符(<slot></slot>
),該佔位符在其中渲染我們的內容。
Web開發中一個經典且更令人沮喪的問題一直是樣式級聯到我們不希望它們出現的地方。您可能擔心應用程序中任何指定類似div.tab
內容的樣式規則都會干擾這些標籤。事實證明這不是問題;shadow roots封裝了樣式。 shadow root外部的樣式不會影響shadow root內部的內容(有一些例外,我們稍後會討論),反之亦然。
對此的例外是可繼承的樣式。當然,您不需要為Web應用程序中的每個元素應用font-family
樣式。相反,您可以在:root
或html
上一次指定您的font-family
,並讓它在它下面的所有地方繼承。這種繼承實際上也會穿透shadow root。
CSS自定義屬性(通常稱為“css變量”)是一個相關的例外。 shadow root絕對可以讀取在shadow root外部定義的CSS屬性;這將在稍後變得相關。
::part
選擇器那麼不可繼承的樣式呢?如果我們想自定義shadow root內部某些內容(例如不繼承的cursor
),我們運氣不好嗎?事實證明我們沒有。再次查看上面的標籤元素圖像及其shadow root。注意div上的part
屬性?這允許您使用::part
選擇器從shadow root外部定位和設置該元素的樣式。我們將逐步介紹一個示例。
讓我們看看這些方法的實際應用。截至目前,許多Shoelace樣式(包括字體)從CSS自定義屬性接收默認值。要使這些字體與應用程序的樣式對齊,請覆蓋相關的自定義屬性。請參閱文檔以了解Shoelace正在使用哪些CSS變量,或者您可以簡單地在DevTools中檢查任何給定元素中的樣式。
打開StackBlitz項目src目錄中的app.css文件。在底部的:root
部分,您應該看到一個letter-spacing: normal;
聲明。由於letter-spacing
屬性是可繼承的,請嘗試設置一個新值,例如2px
。保存後,所有內容(包括在shadow root中定義的標籤標題)都將相應調整。
<sl-tab-group></sl-tab-group>
組件讀取一個--indicator-color
CSS自定義屬性,用於活動標籤的下劃線。我們可以使用一些基本的CSS來覆蓋它:
<sl-tab-group> <sl-tab panel="general" slot="nav">General</sl-tab> <sl-tab panel="custom" slot="nav">Custom</sl-tab> <sl-tab panel="advanced" slot="nav">Advanced</sl-tab> <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab> <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel> <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel> <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel> <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel> </sl-tab-group> <sl-dialog label="Dialog" no-header=""> Hello World! <sl-button> open = false}>Close</sl-button> </sl-dialog> <br><br> <button> open = true}>Open Dialog</button>
就是這樣,我們現在有了綠色的指示器!
在我目前使用的Shoelace版本(2.0.0-beta.83)中,任何非禁用的標籤都有一個指針光標。讓我們將其更改為活動(已選擇)標籤的默認光標。我們已經看到<sl-tab></sl-tab>
元素在標籤標題的容器上添加了一個part="base"
屬性。此外,當前選擇的標籤會接收一個active
屬性。讓我們使用這些事實來定位活動標籤並更改光標:
let tabs;
就是這樣!
為了錦上添花,讓我們看看Shoelace如何允許我們自定義動畫。 Shoelace使用Web Animations API,並公開一個setDefaultAnimation
API來控制不同的元素如何為其各種交互設置動畫。請參閱文檔了解詳細信息,但例如,以下是如何將Shoelace的默認對話框動畫從向外擴展和向內收縮更改為從頂部動畫進入,並在隱藏時向下移動。
<sl-tab-group> <sl-tab panel="general" slot="nav">General</sl-tab> <sl-tab panel="custom" slot="nav">Custom</sl-tab> <sl-tab panel="advanced" slot="nav">Advanced</sl-tab> <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab> <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel> <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel> <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel> <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel> </sl-tab-group> <sl-dialog label="Dialog" no-header=""> Hello World! <sl-button> open = false}>Close</sl-button> </sl-dialog> <br><br> <button> open = true}>Open Dialog</button>
該代碼位於App.svelte文件中。註釋掉它以查看原始的默認動畫。
Shoelace是一個非常雄心勃勃的組件庫,它使用Web Components構建。由於Web Components與框架無關,因此它們可以與任何框架一起用於任何項目。隨著新的框架開始展現出驚人的性能特性以及易用性,能夠使用不受任何一個框架約束的優質用戶體驗組件比以往任何時候都更具吸引力。
以上是介紹鞋款,這是一個獨立於框架的基於組件的UX庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!