


This article introduces Shoelace, a component library created by Cory LaViska, but it is unique. It defines all standard UX components: tags, modal boxes, accordion, autocomplete, and more. These components are out of the box, beautiful, easy to use, and completely customizable. But it does not create these components using frameworks like React, Solid, or Svelte, but uses Web Components; this means you can use them with any framework.
PreparationWeb Components are great, but there are still some minor issues to pay attention to at the moment.
React
I've said before that they can be used in any JavaScript framework, but I've also written before that React's support for Web Components is currently poor. To solve this problem, Shoelace created wrappers specifically for React.
Another option I personally prefer is to create a lightweight React component that accepts the web component's tag name and all its properties, and then deal with the shortcomings of React. I discussed this option in a previous post. I like this scheme because it is designed to be removed. React's experimental branch has solved the problem of web component interoperability so once published, any lightweight web component interoperability component used can be searched and removed, leaving behind direct web component usage without any React wrappers.
Server-side Rendering (SSR)
As of this writing, support for SSR is also poor. In theory, there is a technique called declarative Shadow DOM (DSD) that can implement SSR. But browser support is limited, and DSD actually requires
server support to work properly, meaning Next, Remix, or any other tool you use on the server will need some special processing power. That is, there are other ways to make Web Components "work properly" with web applications that use tools such as Next for SSR. In short, a script that registers Web Components needs to be run in a blocking script before parsing the tag. But this will be the subject of another post.
Of course, if you are building any type of client rendering SPA, this is not a problem. This is what we will use in this post.
Start
Since I want this post to focus on Shoelace and its web component features, I will use Svelte for everything. I will also use this Stackblitz project for demonstration. We will build this demo step by step together, but you can open REPL at any time to see the final result.
I will show you how to use Shoelace and, more importantly, how to customize it. We'll discuss Shadow DOM and what external styles they block (and which styles are not blocked). We'll also discuss the
CSS selector – which may be brand new to you – we'll even see how Shoelace allows us to overwrite and customize its various animations.If you find yourself enjoying Shoelace after reading this article and want to try it in your React project, my suggestion is to use the wrapper mentioned in my introduction. This will allow you to use any component of Shoelace and you can remove it completely once React releases the web component fix they already have (find in version 19).
Shoelace introduction
Shoelace has quite detailed installation instructions. The easiest way is to add the <script></script>
and <link>
tags to your HTML document, and that's it. However, for any production application, you may just want to selectively import what you want, and there are instructions accordingly as well.
After installing Shoelace, let's create a Svelte component to render some content, and then go through the steps of fully customizing it. To select some more complex content, I used the tags and dialogs (often called modal boxes) components. Here are some tags that mainly come from the documentation:
<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>
This will present some beautiful and styled labels. The underscore of the activity tag even animates well and slides from one activity tag to the next.
I won't waste your time detailing each API that has been documented in detail on the Shoelace website. Instead, let's look at how best to interact and fully customize these Web Components.
Interact with API: Methods and Events
Calling methods and subscription events on web components may be slightly different from the normal framework you are used to, but this is not too complicated. Let's see how to do it.
Tags
TheTag component (<sl-tab-group></sl-tab-group>
) has a show
method that displays a specific tag manually. In order to call it, we need to access the underlying DOM element of the tag. In Svelte, this means using bind:this
. In React, it will be a ref. etc. Since we are using Svelte, let's declare a tag instance variable:
let tabs;
…and bind it:
<sl-tab-group bind:this="{tabs}"></sl-tab-group>
Now we can add a button to call it:
<button on:click="{()"> tabs.show("custom")}>Show custom</button>The same is true for the
Events. When a new tag is displayed, a sl-tab-show
event is triggered. We can use tabs
for our addEventListener
variable, or we can use Svelte's on:event-name
shortcut.
<sl-tab-group bind:this="{tabs}" on:sl-tab-show="{e"> console.log(e)}></sl-tab-group>
This works and logs event objects when different tags are displayed.
Usually we render the tags and let the user click between them, so this work is usually not even needed, but if you need it, it's there. Now let's make the dialog components interactive.
Dialogue
The dialog component (<sl-dialog></sl-dialog>
) accepts a open
attribute that controls whether the dialog box... is open. Let's declare it in our Svelte component:
<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>
It also has a sl-hide
event for hiding the dialog box. Let's pass our open
property and bind to the hidden event so that when the user clicks to close it outside the dialog content, we can reset it. Let's add a click handler to that close button to set our open
property to false, which will also close the dialog.
let tabs;
Finally, let's connect our Open dialog button:
<sl-tab-group bind:this="{tabs}"></sl-tab-group>
That's it. Interaction with the component library's API is more or less direct. If this article only does this, it would be quite boring.
But Shoelace - built with Web Components - means that something, especially styles, works slightly differently than what we are used to.
Customize all styles!
At the time of writing, Shoelace is still in beta, and the creators are considering changing some default styles, and maybe even removing some default styles altogether so they don't overwrite the styles of the host application anymore. The concepts we will introduce are relevant anyway, but don't be surprised if some of the Shoelace details I mentioned differ when you use it.
Shoelace's default style is good, but our web application may also have its own design and hope our UX components match it. Let's see how to do this in the world of Web Components.
We are not trying to actually improve anything. The creator of Shoelace is better at design than I do. Instead, we just look at how to change stuff so you can adapt to your own web application. Quick View Shadow DOM
View one of the tag titles in your DevTools; it should look like this:
Our tag element creates a div container with
and classes and a .tab
, while also displaying the text we entered for that tag. But please note that it is located within .tab--active
shadow roottabindex
. This allows web component authors to add their own tags to web components, while also providing a place to place what we provide. Pay attention to the elements? This basically means "put whatever the user renders between web component tags in here <slot></slot>
".
So the
) where it renders our content. <sl-tab></sl-tab>
<slot></slot>
Packaging Style
A classic and more frustrating problem in web development has always been style cascading where we don't want them to appear. You may be worried that any style rules in the application that specify something like
will interfere with these tags. It turns out that this is not a problem; shadow roots encapsulate the style. The style outside the shadow root does not affect what is inside the shadow root (with some exceptions, which we will discuss later), and vice versa.Exception to this is an inheritable style. Of course, you don't need to apply font-family
styles for every element in your web application. Instead, you can specify your :root
or html
last time and let it inherit everything under it. This inheritance will actually penetrate shadow root. font-family
Selector::part
What about the styles that are not inherited? If we want to customize something inside the shadow root (such as that does not inherit), are we unlucky? It turns out we didn't. Check out the above label element image and its shadow root again. Pay attention to the attribute on the div? This allows you to locate and style the element from outside the shadow root using the selector. We will introduce an example step by step. cursor
part
Overwrite Shoelace style::part
Inherit styles through shadow root
Open the app.css file in the src directory of the StackBlitz project. In the section at the bottom, you should see a
statement. Since theattribute is inheritable, try setting a new value, such as
. After saving, all content (including the tag title defined in shadow root) will be adjusted accordingly.
:root
Overwrite Shoelace CSS variablesletter-spacing: normal;
The letter-spacing
2px
component reads a
That's it, we now have the green indicator! <sl-tab-group></sl-tab-group>
--indicator-color
Inquiry Parts
<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>In the Shoelace version I am currently using (2.0.0-beta.83), any non-disabled tag has a pointer cursor. Let's change it to the default cursor for the active (selected) tag. We have seen the
element add a
attribute on the container of the tag title. Additionally, the currently selected tag receives aattribute. Let's use these facts to locate the active tag and change the cursor:
<sl-tab></sl-tab>
That's it! part="base"
Custom animation
To add icing on the cake, let's see how Shoelace allows us to customize animations. Shoelace uses the Web Animations API and exposes a setDefaultAnimation
API to control how different elements animate their various interactions. See the documentation for more information, but for example, here is how to change Shoelace's default dialog animation from expanding out and shrinking inward to entering from the top animation and moving downward when hidden.
<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>
This code is located in the App.svelte file. Comment out it to see the original default animation.
Summary
Shoelace is a very ambitious component library built using Web Components. Since Web Components are framework-free, they can be used with any framework for any project. As new frameworks begin to show amazing performance features and ease of use, being able to use quality user experience components that are not bound by either framework is more attractive than ever.
The above is the detailed content of Introducing Shoelace, a Framework-Independent Component-Based UX Library. For more information, please follow other related articles on the PHP Chinese website!

GooFonts is a side project signed by a developer-wife and a designer-husband, both of them big fans of typography. We’ve been tagging Google

Pavithra Kodmad asked people for recommendations on what they thought were some of the most timeless articles about web development that have changed their

Learning how to build GraphQL APIs can be quite challenging. But you can learn how to use GraphQL APIs in 10 minutes! And it so happens I've got the perfect

When a component lives in an environment where the data queries populating it live nearby, there is a pretty direct line between the visual component and the

Here's some legit CSS trickery from yuanchuan. There is this CSS property offset-path. Once upon a time, it was called motion-path and then it was renamed. I

Miriam Suzanne explains in a Mozilla Developer video on the subject.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Dreamweaver Mac version
Visual web development tools

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.