首页 > web前端 > css教程 > 介绍鞋款,这是一个独立于框架的基于组件的UX库

介绍鞋款,这是一个独立于框架的基于组件的UX库

尊渡假赌尊渡假赌尊渡假赌
发布: 2025-03-10 10:46:10
原创
750 人浏览过

Introducing Shoelace, a Framework-Independent Component-Based UX Library

本文介绍Shoelace,一个由Cory LaViska创建的组件库,但它与众不同。它定义了所有标准的UX组件:标签、模态框、手风琴、自动完成等等。这些组件开箱即用,美观、易用且完全可定制。但它并非使用React、Solid或Svelte等框架创建这些组件,而是使用Web Components;这意味着您可以将它们与任何框架一起使用。

准备工作

Web Components很棒,但目前还有一些小问题需要注意。

React

我之前说过它们可以在任何JavaScript框架中使用,但我之前也写过,React对Web Components的支持目前很差。为了解决这个问题,Shoelace专门为React创建了包装器。

另一个我个人比较喜欢的选择是,创建一个轻量级的React组件,它接受Web组件的标签名称及其所有属性,然后处理React的不足之处。我之前的一篇文章中讨论过这个选项。我喜欢这个方案,因为它旨在被删除。React的实验分支目前已经解决了Web组件互操作性问题,因此一旦发布,任何使用的轻量级Web组件互操作组件都可以被搜索和删除,留下直接的Web组件用法,而无需任何React包装器。

服务器端渲染 (SSR)

在撰写本文时,对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介绍

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。

与API交互:方法和事件

调用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应用程序。

快速浏览Shadow DOM

在您的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样式。相反,您可以在:roothtml上一次指定您的font-family,并让它在它下面的所有地方继承。这种继承实际上也会穿透shadow root。

CSS自定义属性(通常称为“css变量”)是一个相关的例外。shadow root绝对可以读取在shadow root外部定义的CSS属性;这将在稍后变得相关。

::part选择器

那么不可继承的样式呢?如果我们想自定义shadow root内部某些内容(例如不继承的cursor),我们运气不好吗?事实证明我们没有。再次查看上面的标签元素图像及其shadow root。注意div上的part属性?这允许您使用::part选择器从shadow root外部定位和设置该元素的样式。我们将逐步介绍一个示例。

覆盖Shoelace样式

让我们看看这些方法的实际应用。截至目前,许多Shoelace样式(包括字体)从CSS自定义属性接收默认值。要使这些字体与应用程序的样式对齐,请覆盖相关的自定义属性。请参阅文档以了解Shoelace正在使用哪些CSS变量,或者您可以简单地在DevTools中检查任何给定元素中的样式。

通过shadow root继承样式

打开StackBlitz项目src目录中的app.css文件。在底部的:root部分,您应该看到一个letter-spacing: normal;声明。由于letter-spacing属性是可继承的,请尝试设置一个新值,例如2px。保存后,所有内容(包括在shadow root中定义的标签标题)都将相应调整。

覆盖Shoelace CSS变量

<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中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板