buttons, primary, and more

This commit is contained in:
Cory LaViska
2023-09-05 12:01:19 -04:00
parent 55be0a557f
commit ebed8daee6
35 changed files with 326 additions and 491 deletions

View File

@@ -1,4 +1,4 @@
Copyright (c) 2020 A Beautiful Site, LLC
Copyright (c) 2023 Fonticons, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@@ -9,7 +9,7 @@ A forward-thinking library of web components.
- Built with accessibility in mind ♿️
- Open source 😸
Designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska).
Built by the folks behind [Font Awesome](https://fontawesome.com/).
---
@@ -77,16 +77,4 @@ Shoelace is an open source project and contributions are encouraged! If you're i
## License
Shoelace is designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska). Its available under the terms of the MIT license.
Designing, developing, and supporting this library requires a lot of time, effort, and skill. Id like to keep it open source so everyone can use it, but that doesnt provide me with any income.
**Therefore, if youre using my software to make a profit,** I respectfully ask that you help [fund its development](https://github.com/sponsors/claviska) by becoming a sponsor. There are multiple tiers to choose from with benefits at every level, including prioritized support, bug fixes, feature requests, and advertising.
👇 Your support is very much appreciated! 👇
- [Become a sponsor](https://github.com/sponsors/claviska)
- [Star on GitHub](https://github.com/shoelace-style/shoelace/stargazers)
- [Follow on Twitter](https://twitter.com/shoelace_style)
Whether you're building Shoelace or building something _with_ Shoelace — have fun creating! 🥾
Shoelace is available under the terms of the MIT license.

View File

@@ -6,7 +6,7 @@
{% block content %}
{# Determine the badge variant #}
{% if component.status == 'stable' %}
{% set badgeVariant = 'primary' %}
{% set badgeVariant = 'brand' %}
{% elseif component.status == 'experimental' %}
{% set badgeVariant = 'warning' %}
{% elseif component.status == 'planned' %}

View File

@@ -1158,7 +1158,7 @@ html.sidebar-open #menu-toggle {
}
.repo-button--github sl-icon {
color: var(--wa-color-neutral-40);
color: var(--wa-color-white);
}
.repo-button--star sl-icon {

View File

@@ -35,7 +35,7 @@ Alerts will not be visible if the `open` attribute is not present.
Set the `variant` attribute to change the alert's variant.
```html:preview
<sl-alert variant="primary" open>
<sl-alert variant="brand" open>
<sl-icon slot="icon" name="info-circle"></sl-icon>
<strong>This is super informative</strong><br />
You can tell by how pretty the alert is.
@@ -80,7 +80,7 @@ import SlIcon from '@shoelace-style/shoelace/dist/react/icon';
const App = () => (
<>
<SlAlert variant="primary" open>
<SlAlert variant="brand" open>
<SlIcon slot="icon" name="info-circle" />
<strong>This is super informative</strong>
<br />
@@ -131,7 +131,7 @@ const App = () => (
Add the `closable` attribute to show a close button that will hide the alert.
```html:preview
<sl-alert variant="primary" open closable class="alert-closable">
<sl-alert variant="brand" open closable class="alert-closable">
<sl-icon slot="icon" name="info-circle"></sl-icon>
You can close this alert any time!
</sl-alert>
@@ -171,14 +171,14 @@ const App = () => {
Icons are optional. Simply omit the `icon` slot if you don't want them.
```html:preview
<sl-alert variant="primary" open> Nothing fancy here, just a simple alert. </sl-alert>
<sl-alert variant="brand" open> Nothing fancy here, just a simple alert. </sl-alert>
```
```jsx:react
import SlAlert from '@shoelace-style/shoelace/dist/react/alert';
const App = () => (
<SlAlert variant="primary" open>
<SlAlert variant="brand" open>
Nothing fancy here, just a simple alert.
</SlAlert>
);
@@ -190,9 +190,9 @@ Set the `duration` attribute to automatically hide an alert after a period of ti
```html:preview
<div class="alert-duration">
<sl-button variant="primary">Show Alert</sl-button>
<sl-button variant="brand">Show Alert</sl-button>
<sl-alert variant="primary" duration="3000" closable>
<sl-alert variant="brand" duration="3000" closable>
<sl-icon slot="icon" name="info-circle"></sl-icon>
This alert will automatically hide itself after three seconds, unless you interact with it.
</sl-alert>
@@ -231,11 +231,11 @@ const App = () => {
return (
<>
<div className="alert-duration">
<SlButton variant="primary" onClick={() => setOpen(true)}>
<SlButton variant="brand" onClick={() => setOpen(true)}>
Show Alert
</SlButton>
<SlAlert variant="primary" duration="3000" open={open} closable onSlAfterHide={() => setOpen(false)}>
<SlAlert variant="brand" duration="3000" open={open} closable onSlAfterHide={() => setOpen(false)}>
<SlIcon slot="icon" name="info-circle" />
This alert will automatically hide itself after three seconds, unless you interact with it.
</SlAlert>
@@ -255,13 +255,13 @@ You should always use the `closable` attribute so users can dismiss the notifica
```html:preview
<div class="alert-toast">
<sl-button variant="primary">Primary</sl-button>
<sl-button variant="brand">Brand</sl-button>
<sl-button variant="success">Success</sl-button>
<sl-button variant="neutral">Neutral</sl-button>
<sl-button variant="warning">Warning</sl-button>
<sl-button variant="danger">Danger</sl-button>
<sl-alert variant="primary" duration="3000" closable>
<sl-alert variant="brand" duration="3000" closable>
<sl-icon slot="icon" name="info-circle"></sl-icon>
<strong>This is super informative</strong><br />
You can tell by how pretty the alert is.
@@ -295,7 +295,7 @@ You should always use the `closable` attribute so users can dismiss the notifica
<script>
const container = document.querySelector('.alert-toast');
['primary', 'success', 'neutral', 'warning', 'danger'].map(variant => {
['brand', 'success', 'neutral', 'warning', 'danger'].map(variant => {
const button = container.querySelector(`sl-button[variant="${variant}"]`);
const alert = container.querySelector(`sl-alert[variant="${variant}"]`);
@@ -315,7 +315,7 @@ function showToast(alert) {
}
const App = () => {
const primary = useRef(null);
const brand = useRef(null);
const success = useRef(null);
const neutral = useRef(null);
const warning = useRef(null);
@@ -323,8 +323,8 @@ const App = () => {
return (
<>
<SlButton variant="primary" onClick={() => primary.current.toast()}>
Primary
<SlButton variant="brand" onClick={() => brand.current.toast()}>
Brand
</SlButton>
<SlButton variant="success" onClick={() => success.current.toast()}>
@@ -343,7 +343,7 @@ const App = () => {
Danger
</SlButton>
<SlAlert ref={primary} variant="primary" duration="3000" closable>
<SlAlert ref={brand} variant="brand" duration="3000" closable>
<SlIcon slot="icon" name="info-circle" />
<strong>This is super informative</strong>
<br />
@@ -388,7 +388,7 @@ For convenience, you can create a utility that emits toast notifications with a
```html:preview
<div class="alert-toast-wrapper">
<sl-button variant="primary">Create Toast</sl-button>
<sl-button variant="brand">Create Toast</sl-button>
</div>
<script>
@@ -404,7 +404,7 @@ For convenience, you can create a utility that emits toast notifications with a
}
// Custom function to emit toast notifications
function notify(message, variant = 'primary', icon = 'info-circle', duration = 3000) {
function notify(message, variant = 'brand', icon = 'info-circle', duration = 3000) {
const alert = Object.assign(document.createElement('sl-alert'), {
variant,
closable: true,

View File

@@ -312,7 +312,7 @@ Animations won't play until you apply the `play` attribute. You can omit it init
```html:preview
<div class="animation-form">
<sl-animation name="rubberBand" duration="1000" iterations="1">
<sl-button variant="primary">Click me</sl-button>
<sl-button variant="brand">Click me</sl-button>
</sl-animation>
</div>
@@ -338,7 +338,7 @@ const App = () => {
return (
<div class="animation-form">
<SlAnimation name="rubberBand" duration={1000} iterations={1} play={play} onSlFinish={() => setPlay(false)}>
<SlButton variant="primary" onClick={() => setPlay(true)}>
<SlButton variant="brand" onClick={() => setPlay(true)}>
Click me
</SlButton>
</SlAnimation>

View File

@@ -22,7 +22,7 @@ const App = () => <SlBadge>Badge</SlBadge>;
Set the `variant` attribute to change the badge's variant.
```html:preview
<sl-badge variant="primary">Primary</sl-badge>
<sl-badge variant="brand">Brand</sl-badge>
<sl-badge variant="success">Success</sl-badge>
<sl-badge variant="neutral">Neutral</sl-badge>
<sl-badge variant="warning">Warning</sl-badge>
@@ -34,7 +34,7 @@ import SlBadge from '@shoelace-style/shoelace/dist/react/badge';
const App = () => (
<>
<SlBadge variant="primary">Primary</SlBadge>
<SlBadge variant="brand">Brand</SlBadge>
<SlBadge variant="success">Success</SlBadge>
<SlBadge variant="neutral">Neutral</SlBadge>
<SlBadge variant="warning">Warning</SlBadge>
@@ -48,7 +48,7 @@ const App = () => (
Use the `pill` attribute to give badges rounded edges.
```html:preview
<sl-badge variant="primary" pill>Primary</sl-badge>
<sl-badge variant="brand" pill>Brand</sl-badge>
<sl-badge variant="success" pill>Success</sl-badge>
<sl-badge variant="neutral" pill>Neutral</sl-badge>
<sl-badge variant="warning" pill>Warning</sl-badge>
@@ -60,8 +60,8 @@ import SlBadge from '@shoelace-style/shoelace/dist/react/badge';
const App = () => (
<>
<SlBadge variant="primary" pill>
Primary
<SlBadge variant="brand" pill>
Brand
</SlBadge>
<SlBadge variant="success" pill>
Success
@@ -85,7 +85,7 @@ Use the `pulse` attribute to draw attention to the badge with a subtle animation
```html:preview
<div class="badge-pulse">
<sl-badge variant="primary" pill pulse>1</sl-badge>
<sl-badge variant="brand" pill pulse>1</sl-badge>
<sl-badge variant="success" pill pulse>1</sl-badge>
<sl-badge variant="neutral" pill pulse>1</sl-badge>
<sl-badge variant="warning" pill pulse>1</sl-badge>
@@ -111,7 +111,7 @@ const css = `
const App = () => (
<>
<div className="badge-pulse">
<SlBadge variant="primary" pill pulse>
<SlBadge variant="brand" pill pulse>
1
</SlBadge>
<SlBadge variant="success" pill pulse>

View File

@@ -95,9 +95,9 @@ Theme buttons are supported through the button's `variant` attribute.
```html:preview
<sl-button-group label="Alignment">
<sl-button variant="primary">Left</sl-button>
<sl-button variant="primary">Center</sl-button>
<sl-button variant="primary">Right</sl-button>
<sl-button variant="brand">Left</sl-button>
<sl-button variant="brand">Center</sl-button>
<sl-button variant="brand">Right</sl-button>
</sl-button-group>
<br /><br />
@@ -111,9 +111,9 @@ Theme buttons are supported through the button's `variant` attribute.
<br /><br />
<sl-button-group label="Alignment">
<sl-button variant="neutral">Left</sl-button>
<sl-button variant="neutral">Center</sl-button>
<sl-button variant="neutral">Right</sl-button>
<sl-button>Left</sl-button>
<sl-button>Center</sl-button>
<sl-button>Right</sl-button>
</sl-button-group>
<br /><br />
@@ -140,9 +140,9 @@ import SlButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
const App = () => (
<>
<SlButtonGroup label="Alignment">
<SlButton variant="primary">Left</SlButton>
<SlButton variant="primary">Center</SlButton>
<SlButton variant="primary">Right</SlButton>
<SlButton variant="brand">Left</SlButton>
<SlButton variant="brand">Center</SlButton>
<SlButton variant="brand">Right</SlButton>
</SlButtonGroup>
<br />
@@ -158,9 +158,9 @@ const App = () => (
<br />
<SlButtonGroup label="Alignment">
<SlButton variant="neutral">Left</SlButton>
<SlButton variant="neutral">Center</SlButton>
<SlButton variant="neutral">Right</SlButton>
<SlButton>Left</SlButton>
<SlButton>Center</SlButton>
<SlButton>Right</SlButton>
</SlButtonGroup>
<br />
@@ -313,9 +313,9 @@ Create a split button using a button and a dropdown. Use a [visually hidden](/co
```html:preview
<sl-button-group label="Example Button Group">
<sl-button variant="primary">Save</sl-button>
<sl-button variant="brand">Save</sl-button>
<sl-dropdown placement="bottom-end">
<sl-button slot="trigger" variant="primary" caret>
<sl-button slot="trigger" variant="brand" caret>
<sl-visually-hidden>More options</sl-visually-hidden>
</sl-button>
<sl-menu>
@@ -336,9 +336,9 @@ import SlMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
const App = () => (
<SlButtonGroup label="Example Button Group">
<SlButton variant="primary">Save</SlButton>
<SlButton variant="brand">Save</SlButton>
<SlDropdown placement="bottom-end">
<SlButton slot="trigger" variant="primary" caret></SlButton>
<SlButton slot="trigger" variant="brand" caret></SlButton>
<SlMenu>
<SlMenuItem>Save</SlMenuItem>
<SlMenuItem>Save as&hellip;</SlMenuItem>

View File

@@ -22,8 +22,7 @@ const App = () => <SlButton>Button</SlButton>;
Use the `variant` attribute to set the button's variant.
```html:preview
<sl-button variant="default">Default</sl-button>
<sl-button variant="primary">Primary</sl-button>
<sl-button variant="brand">Brand</sl-button>
<sl-button variant="success">Success</sl-button>
<sl-button variant="neutral">Neutral</sl-button>
<sl-button variant="warning">Warning</sl-button>
@@ -35,8 +34,7 @@ import SlButton from '@shoelace-style/shoelace/dist/react/button';
const App = () => (
<>
<SlButton variant="default">Default</SlButton>
<SlButton variant="primary">Primary</SlButton>
<SlButton variant="brand">Brand</SlButton>
<SlButton variant="success">Success</SlButton>
<SlButton variant="neutral">Neutral</SlButton>
<SlButton variant="warning">Warning</SlButton>
@@ -72,8 +70,7 @@ const App = () => (
Use the `outline` attribute to draw outlined buttons with transparent backgrounds.
```html:preview
<sl-button variant="default" outline>Default</sl-button>
<sl-button variant="primary" outline>Primary</sl-button>
<sl-button variant="brand" outline>Brand</sl-button>
<sl-button variant="success" outline>Success</sl-button>
<sl-button variant="neutral" outline>Neutral</sl-button>
<sl-button variant="warning" outline>Warning</sl-button>
@@ -85,11 +82,8 @@ import SlButton from '@shoelace-style/shoelace/dist/react/button';
const App = () => (
<>
<SlButton variant="default" outline>
Default
</SlButton>
<SlButton variant="primary" outline>
Primary
<SlButton variant="brand" outline>
Brand
</SlButton>
<SlButton variant="success" outline>
Success
@@ -135,43 +129,6 @@ const App = () => (
);
```
### Circle Buttons
Use the `circle` attribute to create circular icon buttons. When this attribute is set, the button expects a single `<sl-icon>` in the default slot.
```html:preview
<sl-button variant="default" size="small" circle>
<sl-icon name="gear" label="Settings"></sl-icon>
</sl-button>
<sl-button variant="default" size="medium" circle>
<sl-icon name="gear" label="Settings"></sl-icon>
</sl-button>
<sl-button variant="default" size="large" circle>
<sl-icon name="gear" label="Settings"></sl-icon>
</sl-button>
```
```jsx:react
import SlButton from '@shoelace-style/shoelace/dist/react/button';
import SlIcon from '@shoelace-style/shoelace/dist/react/icon';
const App = () => (
<>
<SlButton variant="default" size="small" circle>
<SlIcon name="gear" />
</SlButton>
<SlButton variant="default" size="medium" circle>
<SlIcon name="gear" />
</SlButton>
<SlButton variant="default" size="large" circle>
<SlIcon name="gear" />
</SlButton>
</>
);
```
### Text Buttons
Use the `text` variant to create text buttons that share the same size as regular buttons but don't have backgrounds or borders.
@@ -239,9 +196,9 @@ When a `target` is set, the link will receive `rel="noreferrer noopener"` for [s
As expected, buttons can be given a custom width by setting the `width` attribute. This is useful for making buttons span the full width of their container on smaller screens.
```html:preview
<sl-button variant="default" size="small" style="width: 100%; margin-bottom: 1rem;">Small</sl-button>
<sl-button variant="default" size="medium" style="width: 100%; margin-bottom: 1rem;">Medium</sl-button>
<sl-button variant="default" size="large" style="width: 100%;">Large</sl-button>
<sl-button size="small" style="width: 100%; margin-bottom: 1rem;">Small</sl-button>
<sl-button size="medium" style="width: 100%; margin-bottom: 1rem;">Medium</sl-button>
<sl-button size="large" style="width: 100%;">Large</sl-button>
```
{% raw %}
@@ -251,13 +208,13 @@ import SlButton from '@shoelace-style/shoelace/dist/react/button';
const App = () => (
<>
<SlButton variant="default" size="small" style={{ width: '100%', marginBottom: '1rem' }}>
<SlButton size="small" style={{ width: '100%', marginBottom: '1rem' }}>
Small
</SlButton>
<SlButton variant="default" size="medium" style={{ width: '100%', marginBottom: '1rem' }}>
<SlButton size="medium" style={{ width: '100%', marginBottom: '1rem' }}>
Medium
</SlButton>
<SlButton variant="default" size="large" style={{ width: '100%' }}>
<SlButton size="large" style={{ width: '100%' }}>
Large
</SlButton>
</>
@@ -271,17 +228,17 @@ const App = () => (
Use the `prefix` and `suffix` slots to add icons.
```html:preview
<sl-button variant="default" size="small">
<sl-button size="small">
<sl-icon slot="prefix" name="gear"></sl-icon>
Settings
</sl-button>
<sl-button variant="default" size="small">
<sl-button size="small">
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh
</sl-button>
<sl-button variant="default" size="small">
<sl-button size="small">
<sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open
@@ -289,17 +246,17 @@ Use the `prefix` and `suffix` slots to add icons.
<br /><br />
<sl-button variant="default">
<sl-button>
<sl-icon slot="prefix" name="gear"></sl-icon>
Settings
</sl-button>
<sl-button variant="default">
<sl-button>
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh
</sl-button>
<sl-button variant="default">
<sl-button>
<sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open
@@ -307,17 +264,17 @@ Use the `prefix` and `suffix` slots to add icons.
<br /><br />
<sl-button variant="default" size="large">
<sl-button size="large">
<sl-icon slot="prefix" name="gear"></sl-icon>
Settings
</sl-button>
<sl-button variant="default" size="large">
<sl-button size="large">
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh
</sl-button>
<sl-button variant="default" size="large">
<sl-button size="large">
<sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open
@@ -330,17 +287,17 @@ import SlIcon from '@shoelace-style/shoelace/dist/react/icon';
const App = () => (
<>
<SlButton variant="default" size="small">
<SlButton size="small">
<SlIcon slot="prefix" name="gear"></SlIcon>
Settings
</SlButton>
<SlButton variant="default" size="small">
<SlButton size="small">
<SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
Refresh
</SlButton>
<SlButton variant="default" size="small">
<SlButton size="small">
<SlIcon slot="prefix" name="link-45deg"></SlIcon>
<SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
Open
@@ -349,17 +306,17 @@ const App = () => (
<br />
<br />
<SlButton variant="default">
<SlButton>
<SlIcon slot="prefix" name="gear"></SlIcon>
Settings
</SlButton>
<SlButton variant="default">
<SlButton>
<SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
Refresh
</SlButton>
<SlButton variant="default">
<SlButton>
<SlIcon slot="prefix" name="link-45deg"></SlIcon>
<SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
Open
@@ -368,17 +325,17 @@ const App = () => (
<br />
<br />
<SlButton variant="default" size="large">
<SlButton size="large">
<SlIcon slot="prefix" name="gear"></SlIcon>
Settings
</SlButton>
<SlButton variant="default" size="large">
<SlButton size="large">
<SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
Refresh
</SlButton>
<SlButton variant="default" size="large">
<SlButton size="large">
<SlIcon slot="prefix" name="link-45deg"></SlIcon>
<SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
Open
@@ -420,8 +377,7 @@ const App = () => (
Use the `loading` attribute to make a button busy. The width will remain the same as before, preventing adjacent elements from moving around. Clicks will be suppressed until the loading state is removed.
```html:preview
<sl-button variant="default" loading>Default</sl-button>
<sl-button variant="primary" loading>Primary</sl-button>
<sl-button variant="brand" loading>Brand</sl-button>
<sl-button variant="success" loading>Success</sl-button>
<sl-button variant="neutral" loading>Neutral</sl-button>
<sl-button variant="warning" loading>Warning</sl-button>
@@ -433,11 +389,8 @@ import SlButton from '@shoelace-style/shoelace/dist/react/button';
const App = () => (
<>
<SlButton variant="default" loading>
Default
</SlButton>
<SlButton variant="primary" loading>
Primary
<SlButton variant="brand" loading>
Brand
</SlButton>
<SlButton variant="success" loading>
Success
@@ -460,8 +413,7 @@ const App = () => (
Use the `disabled` attribute to disable a button.
```html:preview
<sl-button variant="default" disabled>Default</sl-button>
<sl-button variant="primary" disabled>Primary</sl-button>
<sl-button variant="brand" disabled>Brand</sl-button>
<sl-button variant="success" disabled>Success</sl-button>
<sl-button variant="neutral" disabled>Neutral</sl-button>
<sl-button variant="warning" disabled>Warning</sl-button>
@@ -473,12 +425,8 @@ import SlButton from '@shoelace-style/shoelace/dist/react/button';
const App = () => (
<>
<SlButton variant="default" disabled>
Default
</SlButton>
<SlButton variant="primary" disabled>
Primary
<SlButton variant="brand" disabled>
Brand
</SlButton>
<SlButton variant="success" disabled>
@@ -502,18 +450,15 @@ const App = () => (
### Styling Buttons
This example demonstrates how to style buttons using a custom class. This is the recommended approach if you need to add additional variations. To customize an existing variation, modify the selector to target the button's `variant` attribute instead of a class (e.g. `sl-button[variant="primary"]`).
This example demonstrates how to style buttons using a custom class. This is the recommended approach if you need to add additional variations. To customize an existing variation, modify the selector to target the button's `variant` attribute instead of a class (e.g. `sl-button[variant="brand"]`).
```html:preview
<sl-button class="pink">Pink Button</sl-button>
<style>
sl-button.pink::part(base) {
/* Set design tokens for height and border width */
--sl-input-height-medium: 48px;
--sl-input-border-width: 4px;
border-radius: 0;
border-radius: 6px;
border: solid 2px;
background-color: #ff1493;
border-top-color: #ff7ac1;
border-left-color: #ff7ac1;
@@ -522,11 +467,11 @@ This example demonstrates how to style buttons using a custom class. This is the
color: white;
font-size: 1.125rem;
box-shadow: 0 2px 10px #0002;
transition: var(--sl-transition-medium) transform ease, var(--sl-transition-medium) border ease;
transition: var(--wa-transition-normal) all;
}
sl-button.pink::part(base):hover {
transform: scale(1.05) rotate(-1deg);
transform: scale(1.05);
}
sl-button.pink::part(base):active {
@@ -534,7 +479,7 @@ This example demonstrates how to style buttons using a custom class. This is the
border-right-color: #ff7ac1;
border-bottom-color: #ff7ac1;
border-left-color: #ad005c;
transform: scale(1.05) rotate(-1deg) translateY(2px);
transform: translateY(1px);
}
sl-button.pink::part(base):focus-visible {

View File

@@ -18,7 +18,7 @@ layout: component
<small>6 weeks old</small>
<div slot="footer">
<sl-button variant="primary" pill>More Info</sl-button>
<sl-button variant="brand" pill>More Info</sl-button>
<sl-rating></sl-rating>
</div>
</sl-card>
@@ -75,7 +75,7 @@ const App = () => (
<br />
<small>6 weeks old</small>
<div slot="footer">
<SlButton variant="primary" pill>
<SlButton variant="brand" pill>
More Info
</SlButton>
<SlRating></SlRating>
@@ -209,7 +209,7 @@ Footers can be used to display actions, summaries, or other relevant content.
<div slot="footer">
<sl-rating></sl-rating>
<sl-button variant="primary">Preview</sl-button>
<sl-button variant="brand">Preview</sl-button>
</div>
</sl-card>
@@ -249,7 +249,7 @@ const App = () => (
This card has a footer. You can put all sorts of things in it!
<div slot="footer">
<SlRating></SlRating>
<SlButton slot="footer" variant="primary">
<SlButton slot="footer" variant="brand">
Preview
</SlButton>
</div>

View File

@@ -97,7 +97,7 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
<form class="custom-validity">
<sl-checkbox>Check me</sl-checkbox>
<br />
<sl-button type="submit" variant="primary" style="margin-top: 1rem;">Submit</sl-button>
<sl-button type="submit" variant="brand" style="margin-top: 1rem;">Submit</sl-button>
</form>
<script>
const form = document.querySelector('.custom-validity');
@@ -153,7 +153,7 @@ const App = () => {
Check me
</SlCheckbox>
<br />
<SlButton type="submit" variant="primary" style={{ marginTop: '1rem' }}>
<SlButton type="submit" variant="brand" style={{ marginTop: '1rem' }}>
Submit
</SlButton>
</form>

View File

@@ -10,7 +10,7 @@ layout: component
```html:preview
<sl-dialog label="Dialog" class="dialog-overview">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
@@ -37,7 +37,7 @@ const App = () => {
<>
<SlDialog label="Dialog" open={open} onSlAfterHide={() => setOpen(false)}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDialog>
@@ -57,7 +57,7 @@ Use the `--width` custom property to set the dialog's width.
```html:preview
<sl-dialog label="Dialog" class="dialog-width" style="--width: 50vw;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
@@ -86,7 +86,7 @@ const App = () => {
<>
<SlDialog label="Dialog" open={open} style={{ '--width': '50vw' }} onSlAfterHide={() => setOpen(false)}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDialog>
@@ -108,7 +108,7 @@ By design, a dialog's height will never exceed that of the viewport. As such, di
<div style="height: 150vh; border: dashed 2px var(--sl-color-neutral-200); padding: 0 1rem;">
<p>Scroll down and give it a try! 👇</p>
</div>
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
@@ -146,7 +146,7 @@ const App = () => {
<p>Scroll down and give it a try! 👇</p>
</div>
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDialog>
@@ -167,7 +167,7 @@ The header shows a functional close button by default. You can use the `header-a
<sl-dialog label="Dialog" class="dialog-header-actions">
<sl-icon-button class="new-window" slot="header-actions" name="box-arrow-up-right"></sl-icon-button>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
@@ -203,7 +203,7 @@ const App = () => {
onClick={() => window.open(location.href)}
/>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDialog>
@@ -225,7 +225,7 @@ You can use `event.detail.source` to determine what triggered the request to clo
```html:preview
<sl-dialog label="Dialog" class="dialog-deny-close">
This dialog will not close when you click on the overlay.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
@@ -266,7 +266,7 @@ const App = () => {
<>
<SlDialog label="Dialog" open={open} onSlRequestClose={handleRequestClose} onSlAfterHide={() => setOpen(false)}>
This dialog will not close when you click on the overlay.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDialog>
@@ -284,7 +284,7 @@ By default, the dialog's panel will gain focus when opened. This allows a subseq
```html:preview
<sl-dialog label="Dialog" class="dialog-focus">
<sl-input autofocus placeholder="I will have focus when the dialog is opened"></sl-input>
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
@@ -313,7 +313,7 @@ const App = () => {
<>
<SlDialog label="Dialog" open={open} onSlAfterHide={() => setOpen(false)}>
<SlInput autofocus placeholder="I will have focus when the dialog is opened" />
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDialog>

View File

@@ -10,7 +10,7 @@ layout: component
```html:preview
<sl-drawer label="Drawer" class="drawer-overview">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -18,7 +18,7 @@ layout: component
<script>
const drawer = document.querySelector('.drawer-overview');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -37,7 +37,7 @@ const App = () => {
<>
<SlDrawer label="Drawer" open={open} onSlAfterHide={() => setOpen(false)}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -57,7 +57,7 @@ By default, drawers slide in from the end. To make the drawer slide in from the
```html:preview
<sl-drawer label="Drawer" placement="start" class="drawer-placement-start">
This drawer slides in from the start.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -65,7 +65,7 @@ By default, drawers slide in from the end. To make the drawer slide in from the
<script>
const drawer = document.querySelector('.drawer-placement-start');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -84,7 +84,7 @@ const App = () => {
<>
<SlDrawer label="Drawer" placement="start" open={open} onSlAfterHide={() => setOpen(false)}>
This drawer slides in from the start.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -102,7 +102,7 @@ To make the drawer slide in from the top, set the `placement` attribute to `top`
```html:preview
<sl-drawer label="Drawer" placement="top" class="drawer-placement-top">
This drawer slides in from the top.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -110,7 +110,7 @@ To make the drawer slide in from the top, set the `placement` attribute to `top`
<script>
const drawer = document.querySelector('.drawer-placement-top');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -129,7 +129,7 @@ const App = () => {
<>
<SlDrawer label="Drawer" placement="top" open={open} onSlAfterHide={() => setOpen(false)}>
This drawer slides in from the top.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -147,7 +147,7 @@ To make the drawer slide in from the bottom, set the `placement` attribute to `b
```html:preview
<sl-drawer label="Drawer" placement="bottom" class="drawer-placement-bottom">
This drawer slides in from the bottom.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -155,7 +155,7 @@ To make the drawer slide in from the bottom, set the `placement` attribute to `b
<script>
const drawer = document.querySelector('.drawer-placement-bottom');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -174,7 +174,7 @@ const App = () => {
<>
<SlDrawer label="Drawer" placement="bottom" open={open} onSlAfterHide={() => setOpen(false)}>
This drawer slides in from the bottom.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -199,7 +199,7 @@ Unlike normal drawers, contained drawers are not modal. This means they do not s
<sl-drawer label="Drawer" contained class="drawer-contained" style="--size: 50%;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
</div>
@@ -208,7 +208,7 @@ Unlike normal drawers, contained drawers are not modal. This means they do not s
<script>
const drawer = document.querySelector('.drawer-contained');
const openButton = drawer.parentElement.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => (drawer.open = !drawer.open));
closeButton.addEventListener('click', () => drawer.hide());
@@ -247,7 +247,7 @@ const App = () => {
style={{ '--size': '50%' }}
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -268,7 +268,7 @@ Use the `--size` custom property to set the drawer's size. This will be applied
```html:preview
<sl-drawer label="Drawer" class="drawer-custom-size" style="--size: 50vw;">
This drawer is always 50% of the viewport.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -276,7 +276,7 @@ Use the `--size` custom property to set the drawer's size. This will be applied
<script>
const drawer = document.querySelector('.drawer-custom-size');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -297,7 +297,7 @@ const App = () => {
<>
<SlDrawer label="Drawer" open={open} onSlAfterHide={() => setOpen(false)} style={{ '--size': '50vw' }}>
This drawer is always 50% of the viewport.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -319,7 +319,7 @@ By design, a drawer's height will never exceed 100% of its container. As such, d
<div style="height: 150vh; border: dashed 2px var(--sl-color-neutral-200); padding: 0 1rem;">
<p>Scroll down and give it a try! 👇</p>
</div>
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -327,7 +327,7 @@ By design, a drawer's height will never exceed 100% of its container. As such, d
<script>
const drawer = document.querySelector('.drawer-scrolling');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -356,7 +356,7 @@ const App = () => {
>
<p>Scroll down and give it a try! 👇</p>
</div>
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -377,7 +377,7 @@ The header shows a functional close button by default. You can use the `header-a
<sl-drawer label="Drawer" class="drawer-header-actions">
<sl-icon-button class="new-window" slot="header-actions" name="box-arrow-up-right"></sl-icon-button>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -385,7 +385,7 @@ The header shows a functional close button by default. You can use the `header-a
<script>
const drawer = document.querySelector('.drawer-header-actions');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
const newWindowButton = drawer.querySelector('.new-window');
openButton.addEventListener('click', () => drawer.show());
@@ -408,7 +408,7 @@ const App = () => {
<SlDrawer label="Drawer" open={open} onSlAfterHide={() => setOpen(false)}>
<SlIconButton slot="header-actions" name="box-arrow-up-right" onClick={() => window.open(location.href)} />
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>
@@ -430,7 +430,7 @@ You can use `event.detail.source` to determine what triggered the request to clo
```html:preview
<sl-drawer label="Drawer" class="drawer-deny-close">
This drawer will not close when you click on the overlay.
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -438,7 +438,7 @@ You can use `event.detail.source` to determine what triggered the request to clo
<script>
const drawer = document.querySelector('.drawer-deny-close');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -471,7 +471,7 @@ const App = () => {
<>
<SlDrawer label="Drawer" open={open} onSlRequestClose={handleRequestClose} onSlAfterHide={() => setOpen(false)}>
This drawer will not close when you click on the overlay.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Save &amp; Close
</SlButton>
</SlDrawer>
@@ -489,7 +489,7 @@ By default, the drawer's panel will gain focus when opened. This allows a subseq
```html:preview
<sl-drawer label="Drawer" class="drawer-focus">
<sl-input autofocus placeholder="I will have focus when the drawer is opened"></sl-input>
<sl-button slot="footer" variant="primary">Close</sl-button>
<sl-button slot="footer" variant="brand">Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
@@ -498,7 +498,7 @@ By default, the drawer's panel will gain focus when opened. This allows a subseq
const drawer = document.querySelector('.drawer-focus');
const input = drawer.querySelector('sl-input');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[variant="primary"]');
const closeButton = drawer.querySelector('sl-button[variant="brand"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
@@ -518,7 +518,7 @@ const App = () => {
<>
<SlDrawer label="Drawer" open={open} onSlAfterHide={() => setOpen(false)}>
<SlInput autofocus placeholder="I will have focus when the drawer is opened" />
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
<SlButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
Close
</SlButton>
</SlDrawer>

View File

@@ -103,7 +103,7 @@ Add content to the start and end of menu items using the `prefix` and `suffix` s
<sl-menu-item>
<sl-icon slot="prefix" name="envelope"></sl-icon>
Messages
<sl-badge slot="suffix" variant="primary" pill>12</sl-badge>
<sl-badge slot="suffix" variant="brand" pill>12</sl-badge>
</sl-menu-item>
<sl-divider></sl-divider>
@@ -134,7 +134,7 @@ const App = () => (
<SlMenuItem>
<SlIcon slot="prefix" name="envelope" />
Messages
<SlBadge slot="suffix" variant="primary" pill>
<SlBadge slot="suffix" variant="brand" pill>
12
</SlBadge>
</SlMenuItem>

View File

@@ -10,7 +10,7 @@ The mutation observer will report changes to the content it wraps through the `s
```html:preview
<div class="mutation-overview">
<sl-mutation-observer attr="variant">
<sl-button variant="primary">Click to mutate</sl-button>
<sl-button variant="brand">Click to mutate</sl-button>
</sl-mutation-observer>
<br />
@@ -20,7 +20,7 @@ The mutation observer will report changes to the content it wraps through the `s
const container = document.querySelector('.mutation-overview');
const mutationObserver = container.querySelector('sl-mutation-observer');
const button = container.querySelector('sl-button');
const variants = ['primary', 'success', 'neutral', 'warning', 'danger'];
const variants = ['brand', 'success', 'neutral', 'warning', 'danger'];
let clicks = 0;
// Change the button's variant attribute
@@ -54,11 +54,11 @@ const css = `
}
`;
const variants = ['primary', 'success', 'neutral', 'warning', 'danger'];
const variants = ['brand', 'success', 'neutral', 'warning', 'danger'];
let clicks = 0;
const App = () => {
const [variant, setVariant] = useState('primary');
const [variant, setVariant] = useState('brand');
function handleClick() {
clicks++;
@@ -96,7 +96,7 @@ Use the `child-list` attribute to watch for new child elements that are added or
<div class="mutation-child-list">
<sl-mutation-observer child-list>
<div class="buttons">
<sl-button variant="primary">Add button</sl-button>
<sl-button variant="brand">Add button</sl-button>
</div>
</sl-mutation-observer>
@@ -106,7 +106,7 @@ Use the `child-list` attribute to watch for new child elements that are added or
const container = document.querySelector('.mutation-child-list');
const mutationObserver = container.querySelector('sl-mutation-observer');
const buttons = container.querySelector('.buttons');
const button = container.querySelector('sl-button[variant="primary"]');
const button = container.querySelector('sl-button[variant="brand"]');
let i = 0;
// Add a button
@@ -118,7 +118,7 @@ Use the `child-list` attribute to watch for new child elements that are added or
// Remove a button
buttons.addEventListener('click', event => {
const target = event.target.closest('sl-button:not([variant="primary"])');
const target = event.target.closest('sl-button:not([variant="brand"])');
event.stopPropagation();
if (target) {
@@ -175,7 +175,7 @@ const App = () => {
<div className="mutation-child-list">
<SlMutationObserver child-list onSlMutation={event => console.log(event.detail)}>
<div className="buttons">
<SlButton variant="primary" onClick={addButton}>
<SlButton variant="brand" onClick={addButton}>
Add button
</SlButton>
{buttonIds.map(id => (

View File

@@ -167,7 +167,7 @@ Setting the `required` attribute to make selecting an option mandatory. If a val
<sl-radio value="3">Option 3</sl-radio>
</sl-radio-group>
<br />
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
</form>
<script>
@@ -206,7 +206,7 @@ const App = () => {
</SlRadio>
</SlRadioGroup>
<br />
<SlButton type="submit" variant="primary">
<SlButton type="submit" variant="brand">
Submit
</SlButton>
</form>
@@ -226,7 +226,7 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
<sl-radio value="3">Choose me</sl-radio>
</sl-radio-group>
<br />
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
</form>
<script>
@@ -284,7 +284,7 @@ const App = () => {
<SlRadio value="3">Choose me</SlRadio>
</SlRadioGroup>
<br />
<SlButton type="submit" variant="primary">
<SlButton type="submit" variant="brand">
Submit
</SlButton>
</form>

View File

@@ -6,7 +6,7 @@ layout: component
---
```html:preview
<sl-tag variant="primary">Primary</sl-tag>
<sl-tag variant="brand">Brand</sl-tag>
<sl-tag variant="success">Success</sl-tag>
<sl-tag variant="neutral">Neutral</sl-tag>
<sl-tag variant="warning">Warning</sl-tag>
@@ -18,7 +18,7 @@ import SlTag from '@shoelace-style/shoelace/dist/react/tag';
const App = () => (
<>
<SlTag variant="primary">Primary</SlTag>
<SlTag variant="brand">Brand</SlTag>
<SlTag variant="success">Success</SlTag>
<SlTag variant="neutral">Neutral</SlTag>
<SlTag variant="warning">Warning</SlTag>

View File

@@ -41,7 +41,7 @@ Every Shoelace component is available to import as a React component. Note that
```jsx
import SlButton from '@shoelace-style/shoelace/%NPMDIR%/react/button';
const MyComponent = () => <SlButton variant="primary">Click me</SlButton>;
const MyComponent = () => <SlButton variant="brand">Click me</SlButton>;
export default MyComponent;
```

View File

@@ -121,7 +121,7 @@ Here is an example:
<sl-drawer label="Drawer" placement="start" class="drawer-placement-start" :open="drawerIsOpen">
This drawer slides in from the start.
<div slot="footer">
<sl-button variant="primary" @click=" drawerIsOpen = false">Close</sl-button>
<sl-button variant="brand" @click=" drawerIsOpen = false">Close</sl-button>
</div>
</sl-drawer>
```

View File

@@ -75,7 +75,7 @@ The form will not be submitted if a required field is incomplete.
<br />
<sl-checkbox required>Check me before submitting</sl-checkbox>
<br /><br />
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
</form>
<script type="module">
@@ -128,7 +128,7 @@ const App = () => {
<SlCheckbox required>Check me before submitting</SlCheckbox>
<br />
<br />
<SlButton type="submit" variant="primary">
<SlButton type="submit" variant="brand">
Submit
</SlButton>
</form>
@@ -144,7 +144,7 @@ To restrict a value to a specific [pattern](https://developer.mozilla.org/en-US/
<form class="input-validation-pattern">
<sl-input name="letters" required label="Letters" pattern="[A-Za-z]+"></sl-input>
<br />
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
<sl-button type="reset" variant="default">Reset</sl-button>
</form>
@@ -178,7 +178,7 @@ const App = () => {
<form onSubmit={handleSubmit}>
<SlInput name="letters" required label="Letters" pattern="[A-Za-z]+" />
<br />
<SlButton type="submit" variant="primary">
<SlButton type="submit" variant="brand">
Submit
</SlButton>
</form>
@@ -196,7 +196,7 @@ Some input types will automatically trigger constraints, such as `email` and `ur
<br />
<sl-input type="url" label="URL" placeholder="https://example.com/" required></sl-input>
<br />
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
<sl-button type="reset" variant="default">Reset</sl-button>
</form>
@@ -232,7 +232,7 @@ const App = () => {
<br />
<SlInput type="url" label="URL" placeholder="https://example.com/" required />
<br />
<SlButton type="submit" variant="primary">
<SlButton type="submit" variant="brand">
Submit
</SlButton>
</form>
@@ -248,7 +248,7 @@ To create a custom validation error, pass a non-empty string to the `setCustomVa
<form class="input-validation-custom">
<sl-input label="Type “shoelace”" required></sl-input>
<br />
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
<sl-button type="reset" variant="default">Reset</sl-button>
</form>
@@ -305,7 +305,7 @@ const App = () => {
<form onSubmit={handleSubmit}>
<SlInput ref={input} label="Type 'shoelace'" required value={value} onSlInput={handleInput} />
<br />
<SlButton type="submit" variant="primary">
<SlButton type="submit" variant="brand">
Submit
</SlButton>
</form>
@@ -359,7 +359,7 @@ This example demonstrates custom validation styles using `data-user-invalid` and
<sl-checkbox value="accept" required>Accept terms and conditions</sl-checkbox>
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
<sl-button type="reset" variant="default">Reset</sl-button>
</form>
@@ -458,7 +458,7 @@ To disable the browser's error messages, you need to cancel the `sl-invalid` eve
<div id="name-error" aria-live="polite" hidden></div>
<sl-button type="submit" variant="primary">Submit</sl-button>
<sl-button type="submit" variant="brand">Submit</sl-button>
<sl-button type="reset" variant="default">Reset</sl-button>
</form>

View File

@@ -106,10 +106,6 @@ Critical bug fixes in earlier versions will be addressed based on their severity
If you need to support IE11 or pre-Chromium Edge, this library isn't for you. Although web components can (to some degree) be polyfilled for legacy browsers, supporting them is outside the scope of this project. If you're using Shoelace in such a browser, you're gonna have a bad time. ⛷
## License
Shoelace was created in New Hampshire by [Cory LaViska](https://twitter.com/claviska). It's available under the terms of the [MIT license](https://github.com/shoelace-style/shoelace/blob/next/LICENSE.md).
## Attribution
Special thanks to the following projects and individuals that help make Shoelace possible.

View File

@@ -6,12 +6,18 @@ meta:
# Changelog
Shoelace follows [Semantic Versioning](https://semver.org/). Breaking changes in components with the <sl-badge variant="primary" pill>Stable</sl-badge> badge will not be accepted until the next major version. As such, all contributions must consider the project's roadmap and take this into consideration. Features that are deemed no longer necessary will be deprecated but not removed.
Shoelace follows [Semantic Versioning](https://semver.org/). Breaking changes in components with the <sl-badge variant="brand" pill>Stable</sl-badge> badge will not be accepted until the next major version. As such, all contributions must consider the project's roadmap and take this into consideration. Features that are deemed no longer necessary will be deprecated but not removed.
Components with the <sl-badge variant="warning" pill>Experimental</sl-badge> badge should not be used in production. They are made available as release candidates for development and testing purposes. As such, changes to experimental components will not be subject to semantic versioning.
New versions of Shoelace are released as-needed and generally occur when a critical mass of changes have accumulated. At any time, you can see what's coming in the next release by visiting [next.shoelace.style](https://next.shoelace.style).
## Theme API
- Changed `primary` variants to `brand` in all components
- Removed `default` from `<sl-button>` and made `neutral` the new default
- Removed the `circle` modifier from `<sl-button>` because button's no longer have a set height
## Next
- Fixed a bug in `<sl-switch>` that resulted in improper spacing between the label and the required asterisk [#1540]

View File

@@ -19,7 +19,7 @@ The [discussion forum](https://github.com/shoelace-style/shoelace/discussions) i
- Show the community what you're working on
- Learn more about the project, its values, and its roadmap
<sl-button variant="primary" href="https://github.com/shoelace-style/shoelace/discussions" target="_blank">
<sl-button variant="brand" href="https://github.com/shoelace-style/shoelace/discussions" target="_blank">
<sl-icon name="github" slot="prefix"></sl-icon>
Join the Discussion
</sl-button>
@@ -33,7 +33,7 @@ The [community chat](https://discord.gg/mg8f26C) is open to the public and power
- Show the community what you're working on
- Chat live with other designers, developers, and Shoelace fans
<sl-button variant="primary" href="https://discord.gg/mg8f26C" target="_blank">
<sl-button variant="brand" href="https://discord.gg/mg8f26C" target="_blank">
<sl-icon name="discord" slot="prefix"></sl-icon>
Join the Chat
</sl-button>
@@ -42,7 +42,7 @@ The [community chat](https://discord.gg/mg8f26C) is open to the public and power
You can post questions on Stack Overflow using [the "shoelace" tag](https://stackoverflow.com/questions/tagged/shoelace). This is a public forum where talented developers answer questions. It's a great way to get help, but it is not maintained by the Shoelace author.
<sl-button variant="primary" href="https://stackoverflow.com/questions/ask?tags=shoelace" target="_blank">
<sl-button variant="brand" href="https://stackoverflow.com/questions/ask?tags=shoelace" target="_blank">
<sl-icon name="stack-overflow" slot="prefix"></sl-icon>
Ask for Help
</sl-button>
@@ -53,7 +53,7 @@ Follow [@shoelace_style](https://twitter.com/shoelace_style) on Twitter for gene
**Please avoid using Twitter for support questions.** The [discussion forum](https://github.com/shoelace-style/shoelace/discussions) is a much better place to share code snippets, screenshots, and other troubleshooting info. You'll have much better luck there, as more users will have a chance to help you.
<sl-button variant="primary" href="https://twitter.com/shoelace_style" target="_blank">
<sl-button variant="brand" href="https://twitter.com/shoelace_style" target="_blank">
<sl-icon name="twitter" slot="prefix"></sl-icon>
Follow on Twitter
</sl-button>

View File

@@ -3,7 +3,7 @@
"description": "A forward-thinking library of web components.",
"version": "2.8.0",
"homepage": "https://github.com/shoelace-style/shoelace",
"author": "Cory LaViska",
"author": "Web Awesome",
"license": "MIT",
"customElements": "dist/custom-elements.json",
"web-types": "./web-types.json",

View File

@@ -59,7 +59,7 @@ export default class SlAlert extends ShoelaceElement {
@property({ type: Boolean, reflect: true }) closable = false;
/** The alert's theme variant. */
@property({ reflect: true }) variant: 'primary' | 'success' | 'neutral' | 'warning' | 'danger' = 'primary';
@property({ reflect: true }) variant: 'brand' | 'success' | 'neutral' | 'warning' | 'danger' = 'brand';
/**
* The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with
@@ -188,7 +188,7 @@ export default class SlAlert extends ShoelaceElement {
'alert--open': this.open,
'alert--closable': this.closable,
'alert--has-icon': this.hasSlotController.test('icon'),
'alert--primary': this.variant === 'primary',
'alert--brand': this.variant === 'brand',
'alert--success': this.variant === 'success',
'alert--neutral': this.variant === 'neutral',
'alert--warning': this.variant === 'warning',

View File

@@ -40,11 +40,11 @@ export default css`
padding-inline-start: var(--sl-spacing-large);
}
.alert--primary {
.alert--brand {
border-top-color: var(--sl-color-primary-600);
}
.alert--primary .alert__icon {
.alert--brand .alert__icon {
color: var(--sl-color-primary-600);
}

View File

@@ -292,7 +292,7 @@ describe('<sl-alert>', () => {
});
describe('alert variants', () => {
const variants = ['primary', 'success', 'neutral', 'warning', 'danger'];
const variants = ['brand', 'success', 'neutral', 'warning', 'danger'];
variants.forEach(variant => {
it(`adapts to the variant: ${variant}`, async () => {

View File

@@ -19,7 +19,7 @@ export default class SlBadge extends ShoelaceElement {
static styles: CSSResultGroup = styles;
/** The badge's theme variant. */
@property({ reflect: true }) variant: 'primary' | 'success' | 'neutral' | 'warning' | 'danger' = 'primary';
@property({ reflect: true }) variant: 'brand' | 'success' | 'neutral' | 'warning' | 'danger' = 'brand';
/** Draws a pill-style badge with rounded edges. */
@property({ type: Boolean, reflect: true }) pill = false;
@@ -33,7 +33,7 @@ export default class SlBadge extends ShoelaceElement {
part="base"
class=${classMap({
badge: true,
'badge--primary': this.variant === 'primary',
'badge--brand': this.variant === 'brand',
'badge--success': this.variant === 'success',
'badge--neutral': this.variant === 'neutral',
'badge--warning': this.variant === 'warning',

View File

@@ -24,7 +24,7 @@ export default css`
}
/* Variant modifiers */
.badge--primary {
.badge--brand {
background-color: var(--wa-color-brand-element-fill-vivid);
color: var(--wa-color-brand-text-on-vivid);
}
@@ -59,7 +59,7 @@ export default css`
animation: pulse 1.5s infinite;
}
.badge--pulse.badge--primary {
.badge--pulse.badge--brand {
--pulse-color: var(--wa-color-brand-container-outline-vivid);
}

View File

@@ -25,9 +25,9 @@ describe('<sl-badge>', () => {
expect(el.innerText).to.eq('Badge');
});
it('should default to square styling, with the primary color', () => {
it('should default to square styling, with the brand color', () => {
const part = el.shadowRoot!.querySelector('[part~="base"]')!;
expect(part.classList.value.trim()).to.eq('badge badge--primary');
expect(part.classList.value.trim()).to.eq('badge badge--brand');
});
});
@@ -42,7 +42,7 @@ describe('<sl-badge>', () => {
it('should append the pill class to the classlist to render a pill', () => {
const part = el.shadowRoot!.querySelector('[part~="base"]')!;
expect(part.classList.value.trim()).to.eq('badge badge--primary badge--pill');
expect(part.classList.value.trim()).to.eq('badge badge--brand badge--pill');
});
});
@@ -57,11 +57,11 @@ describe('<sl-badge>', () => {
it('should append the pulse class to the classlist to render a pulse', () => {
const part = el.shadowRoot!.querySelector('[part~="base"]')!;
expect(part.classList.value.trim()).to.eq('badge badge--primary badge--pulse');
expect(part.classList.value.trim()).to.eq('badge badge--brand badge--pulse');
});
});
['primary', 'success', 'neutral', 'warning', 'danger'].forEach(variant => {
['brand', 'success', 'neutral', 'warning', 'danger'].forEach(variant => {
describe(`when passed a variant attribute ${variant}`, () => {
before(async () => {
el = await fixture<SlBadge>(html`<sl-badge variant="${variant}">Badge</sl-badge>`);
@@ -71,7 +71,7 @@ describe('<sl-badge>', () => {
await expect(el).to.be.accessible({ ignoredRules });
});
it('should default to square styling, with the primary color', () => {
it('should default to square styling, with the correct color', () => {
const part = el.shadowRoot!.querySelector('[part~="base"]')!;
expect(part.classList.value.trim()).to.eq(`badge badge--${variant}`);
});

View File

@@ -69,8 +69,7 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
@property() title = ''; // make reactive to pass through
/** The button's theme variant. */
@property({ reflect: true }) variant: 'default' | 'primary' | 'success' | 'neutral' | 'warning' | 'danger' | 'text' =
'default';
@property({ reflect: true }) variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'text' = 'neutral';
/** The button's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@@ -90,12 +89,6 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
/** Draws a pill-style button with rounded edges. */
@property({ type: Boolean, reflect: true }) pill = false;
/**
* Draws a circular icon button. When this attribute is present, the button expects a single `<sl-icon>` in the
* default slot.
*/
@property({ type: Boolean, reflect: true }) circle = false;
/**
* The type of button. Note that the default value is `button` instead of `submit`, which is opposite of how native
* `<button>` elements behave. When the type is `submit`, the button will submit the surrounding form.
@@ -187,7 +180,7 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
this.emit('sl-focus');
}
private handleClick() {
private handleClick(event: MouseEvent) {
if (this.type === 'submit') {
this.formControlController.submit(this);
}
@@ -195,6 +188,10 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
if (this.type === 'reset') {
this.formControlController.reset(this);
}
if (this.href) {
event.preventDefault();
}
}
private handleInvalid(event: Event) {
@@ -275,8 +272,7 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
part="base"
class=${classMap({
button: true,
'button--default': this.variant === 'default',
'button--primary': this.variant === 'primary',
'button--brand': this.variant === 'brand',
'button--success': this.variant === 'success',
'button--neutral': this.variant === 'neutral',
'button--warning': this.variant === 'warning',
@@ -286,7 +282,6 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
'button--medium': this.size === 'medium',
'button--large': this.size === 'large',
'button--caret': this.caret,
'button--circle': this.circle,
'button--disabled': this.disabled,
'button--focused': this.hasFocus,
'button--loading': this.loading,

View File

@@ -16,17 +16,16 @@ export default css`
align-items: stretch;
justify-content: center;
width: 100%;
border-style: solid;
border-width: var(--sl-input-border-width);
font-family: var(--sl-input-font-family);
font-weight: var(--sl-font-weight-semibold);
border: none;
font-family: var(--wa-font-family-body);
font-weight: var(--wa-font-weight-normal);
text-decoration: none;
user-select: none;
white-space: nowrap;
vertical-align: middle;
padding: 0;
transition: var(--sl-transition-x-fast) background-color, var(--sl-transition-x-fast) color,
var(--sl-transition-x-fast) border, var(--sl-transition-x-fast) box-shadow;
transition: var(--wa-transition-faster) background-color, var(--wa-transition-faster) color,
var(--wa-transition-faster) border, var(--wa-transition-faster) box-shadow;
cursor: inherit;
}
@@ -39,8 +38,28 @@ export default css`
}
.button:focus-visible {
outline: var(--sl-focus-ring);
outline-offset: var(--sl-focus-ring-offset);
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.button--brand:focus-visible {
outline-color: var(--wa-color-brand-container-fill-vivid);
}
.button--success:focus-visible {
outline-color: var(--wa-color-success-container-fill-vivid);
}
.button--neutral:focus-visible {
outline-color: var(--wa-color-neutral-container-fill-vivid);
}
.button--warning:focus-visible {
outline-color: var(--wa-color-warning-container-fill-vivid);
}
.button--danger:focus-visible {
outline-color: var(--wa-color-danger-container-fill-vivid);
}
.button--disabled {
@@ -73,117 +92,73 @@ export default css`
* Standard buttons
*/
/* Default */
.button--standard.button--default {
background-color: var(--sl-color-neutral-0);
border-color: var(--sl-color-neutral-300);
color: var(--sl-color-neutral-700);
/* Brand */
.button--standard.button--brand {
background-color: var(--wa-color-brand-container-fill-vivid);
color: var(--wa-color-brand-text-on-vivid);
}
.button--standard.button--default:hover:not(.button--disabled) {
background-color: var(--sl-color-primary-50);
border-color: var(--sl-color-primary-300);
color: var(--sl-color-primary-700);
.button--standard.button--brand:hover:not(.button--disabled) {
background-color: color-mix(in oklch, var(--wa-color-brand-container-fill-vivid), white 6%);
}
.button--standard.button--default:active:not(.button--disabled) {
background-color: var(--sl-color-primary-100);
border-color: var(--sl-color-primary-400);
color: var(--sl-color-primary-700);
}
/* Primary */
.button--standard.button--primary {
background-color: var(--sl-color-primary-600);
border-color: var(--sl-color-primary-600);
color: var(--sl-color-neutral-0);
}
.button--standard.button--primary:hover:not(.button--disabled) {
background-color: var(--sl-color-primary-500);
border-color: var(--sl-color-primary-500);
color: var(--sl-color-neutral-0);
}
.button--standard.button--primary:active:not(.button--disabled) {
background-color: var(--sl-color-primary-600);
border-color: var(--sl-color-primary-600);
color: var(--sl-color-neutral-0);
.button--standard.button--brand:active:not(.button--disabled) {
background-color: color-mix(in oklch, var(--wa-color-brand-container-fill-vivid), black 6%);
}
/* Success */
.button--standard.button--success {
background-color: var(--sl-color-success-600);
border-color: var(--sl-color-success-600);
color: var(--sl-color-neutral-0);
background-color: var(--wa-color-success-container-fill-vivid);
color: var(--wa-color-success-text-on-vivid);
}
.button--standard.button--success:hover:not(.button--disabled) {
background-color: var(--sl-color-success-500);
border-color: var(--sl-color-success-500);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-success-container-fill-vivid), white 6%);
}
.button--standard.button--success:active:not(.button--disabled) {
background-color: var(--sl-color-success-600);
border-color: var(--sl-color-success-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-success-container-fill-vivid), black 6%);
}
/* Neutral */
.button--standard.button--neutral {
background-color: var(--sl-color-neutral-600);
border-color: var(--sl-color-neutral-600);
color: var(--sl-color-neutral-0);
background-color: var(--wa-color-neutral-container-fill-vivid);
color: var(--wa-color-neutral-text-on-vivid);
}
.button--standard.button--neutral:hover:not(.button--disabled) {
background-color: var(--sl-color-neutral-500);
border-color: var(--sl-color-neutral-500);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-neutral-container-fill-vivid), white 6%);
}
.button--standard.button--neutral:active:not(.button--disabled) {
background-color: var(--sl-color-neutral-600);
border-color: var(--sl-color-neutral-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-neutral-container-fill-vivid), black 6%);
}
/* Warning */
.button--standard.button--warning {
background-color: var(--sl-color-warning-600);
border-color: var(--sl-color-warning-600);
color: var(--sl-color-neutral-0);
background-color: var(--wa-color-warning-container-fill-vivid);
color: var(--wa-color-warning-text-on-vivid);
}
.button--standard.button--warning:hover:not(.button--disabled) {
background-color: var(--sl-color-warning-500);
border-color: var(--sl-color-warning-500);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-warning-container-fill-vivid), white 6%);
}
.button--standard.button--warning:active:not(.button--disabled) {
background-color: var(--sl-color-warning-600);
border-color: var(--sl-color-warning-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-warning-container-fill-vivid), black 6%);
}
/* Danger */
.button--standard.button--danger {
background-color: var(--sl-color-danger-600);
border-color: var(--sl-color-danger-600);
color: var(--sl-color-neutral-0);
background-color: var(--wa-color-danger-container-fill-vivid);
color: var(--wa-color-danger-text-on-vivid);
}
.button--standard.button--danger:hover:not(.button--disabled) {
background-color: var(--sl-color-danger-500);
border-color: var(--sl-color-danger-500);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-danger-container-fill-vivid), white 6%);
}
.button--standard.button--danger:active:not(.button--disabled) {
background-color: var(--sl-color-danger-600);
border-color: var(--sl-color-danger-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-danger-container-fill-vivid), black 6%);
}
/*
@@ -195,113 +170,94 @@ export default css`
border: solid 1px;
}
/* Default */
.button--outline.button--default {
border-color: var(--sl-color-neutral-300);
color: var(--sl-color-neutral-700);
/* Brand */
.button--outline.button--brand {
border-color: var(--wa-color-brand-element-outline-vivid);
color: var(--wa-color-brand-text-on-surface);
}
.button--outline.button--default:hover:not(.button--disabled),
.button--outline.button--default.button--checked:not(.button--disabled) {
border-color: var(--sl-color-primary-600);
background-color: var(--sl-color-primary-600);
color: var(--sl-color-neutral-0);
.button--outline.button--brand:hover:not(.button--disabled),
.button--outline.button--brand.button--checked:not(.button--disabled) {
background-color: color-mix(in oklch, var(--wa-color-brand-container-fill-vivid), white 6%);
border-color: color-mix(in oklch, var(--wa-color-brand-container-fill-vivid), white 6%);
color: var(--wa-color-brand-text-on-vivid);
}
.button--outline.button--default:active:not(.button--disabled) {
border-color: var(--sl-color-primary-700);
background-color: var(--sl-color-primary-700);
color: var(--sl-color-neutral-0);
}
/* Primary */
.button--outline.button--primary {
border-color: var(--sl-color-primary-600);
color: var(--sl-color-primary-600);
}
.button--outline.button--primary:hover:not(.button--disabled),
.button--outline.button--primary.button--checked:not(.button--disabled) {
background-color: var(--sl-color-primary-600);
color: var(--sl-color-neutral-0);
}
.button--outline.button--primary:active:not(.button--disabled) {
border-color: var(--sl-color-primary-700);
background-color: var(--sl-color-primary-700);
color: var(--sl-color-neutral-0);
.button--outline.button--brand:active:not(.button--disabled) {
background-color: color-mix(in oklch, var(--wa-color-brand-container-fill-vivid), black 6%);
border-color: color-mix(in oklch, var(--wa-color-brand-container-fill-vivid), black 6%);
}
/* Success */
.button--outline.button--success {
border-color: var(--sl-color-success-600);
color: var(--sl-color-success-600);
border-color: var(--wa-color-success-element-outline-vivid);
color: var(--wa-color-success-text-on-surface);
}
.button--outline.button--success:hover:not(.button--disabled),
.button--outline.button--success.button--checked:not(.button--disabled) {
background-color: var(--sl-color-success-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-success-container-fill-vivid), white 6%);
border-color: color-mix(in oklch, var(--wa-color-success-container-fill-vivid), white 6%);
color: var(--wa-color-success-text-on-vivid);
}
.button--outline.button--success:active:not(.button--disabled) {
border-color: var(--sl-color-success-700);
background-color: var(--sl-color-success-700);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-success-container-fill-vivid), black 6%);
border-color: color-mix(in oklch, var(--wa-color-success-container-fill-vivid), black 6%);
}
/* Neutral */
.button--outline.button--neutral {
border-color: var(--sl-color-neutral-600);
color: var(--sl-color-neutral-600);
border-color: var(--wa-color-neutral-element-outline-vivid);
color: var(--wa-color-neutral-text-on-surface);
}
.button--outline.button--neutral:hover:not(.button--disabled),
.button--outline.button--neutral.button--checked:not(.button--disabled) {
background-color: var(--sl-color-neutral-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-neutral-container-fill-vivid), white 6%);
border-color: color-mix(in oklch, var(--wa-color-neutral-container-fill-vivid), white 6%);
color: var(--wa-color-neutral-text-on-vivid);
}
.button--outline.button--neutral:active:not(.button--disabled) {
border-color: var(--sl-color-neutral-700);
background-color: var(--sl-color-neutral-700);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-neutral-container-fill-vivid), black 6%);
border-color: color-mix(in oklch, var(--wa-color-neutral-container-fill-vivid), black 6%);
}
/* Warning */
.button--outline.button--warning {
border-color: var(--sl-color-warning-600);
color: var(--sl-color-warning-600);
border-color: var(--wa-color-warning-element-outline-vivid);
color: var(--wa-color-warning-text-on-surface);
}
.button--outline.button--warning:hover:not(.button--disabled),
.button--outline.button--warning.button--checked:not(.button--disabled) {
background-color: var(--sl-color-warning-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-warning-container-fill-vivid), white 6%);
border-color: color-mix(in oklch, var(--wa-color-warning-container-fill-vivid), white 6%);
color: var(--wa-color-warning-text-on-vivid);
}
.button--outline.button--warning:active:not(.button--disabled) {
border-color: var(--sl-color-warning-700);
background-color: var(--sl-color-warning-700);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-warning-container-fill-vivid), black 6%);
border-color: color-mix(in oklch, var(--wa-color-warning-container-fill-vivid), black 6%);
}
/* Danger */
.button--outline.button--danger {
border-color: var(--sl-color-danger-600);
color: var(--sl-color-danger-600);
border-color: var(--wa-color-danger-element-outline-vivid);
color: var(--wa-color-danger-text-on-surface);
}
.button--outline.button--danger:hover:not(.button--disabled),
.button--outline.button--danger.button--checked:not(.button--disabled) {
background-color: var(--sl-color-danger-600);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-danger-container-fill-vivid), white 6%);
border-color: color-mix(in oklch, var(--wa-color-danger-container-fill-vivid), white 6%);
color: var(--wa-color-danger-text-on-vivid);
}
.button--outline.button--danger:active:not(.button--disabled) {
border-color: var(--sl-color-danger-700);
background-color: var(--sl-color-danger-700);
color: var(--sl-color-neutral-0);
background-color: color-mix(in oklch, var(--wa-color-danger-container-fill-vivid), black 6%);
border-color: color-mix(in oklch, var(--wa-color-danger-container-fill-vivid), black 6%);
}
@media (forced-colors: active) {
@@ -317,25 +273,16 @@ export default css`
.button--text {
background-color: transparent;
border-color: transparent;
color: var(--sl-color-primary-600);
color: var(--wa-color-text-link);
}
.button--text:hover:not(.button--disabled) {
background-color: transparent;
border-color: transparent;
color: var(--sl-color-primary-500);
}
.button--text:focus-visible:not(.button--disabled) {
background-color: transparent;
border-color: transparent;
color: var(--sl-color-primary-500);
color: color-mix(in oklch, var(--wa-color-text-link), white 6%);
}
.button--text:focus-visible:not(.button--disabled),
.button--text:active:not(.button--disabled) {
background-color: transparent;
border-color: transparent;
color: var(--sl-color-primary-700);
color: var(--wa-color-text-link);
}
/*
@@ -344,26 +291,20 @@ export default css`
.button--small {
height: auto;
min-height: var(--sl-input-height-small);
font-size: var(--sl-button-font-size-small);
line-height: calc(var(--sl-input-height-small) - var(--sl-input-border-width) * 2);
border-radius: var(--sl-input-border-radius-small);
font-size: var(--wa-font-size-s);
border-radius: var(--wa-corners-1x);
}
.button--medium {
height: auto;
min-height: var(--sl-input-height-medium);
font-size: var(--sl-button-font-size-medium);
line-height: calc(var(--sl-input-height-medium) - var(--sl-input-border-width) * 2);
border-radius: var(--sl-input-border-radius-medium);
font-size: var(--wa-font-size-m);
border-radius: var(--wa-corners-1x);
}
.button--large {
height: auto;
min-height: var(--sl-input-height-large);
font-size: var(--sl-button-font-size-large);
line-height: calc(var(--sl-input-height-large) - var(--sl-input-border-width) * 2);
border-radius: var(--sl-input-border-radius-large);
font-size: var(--wa-font-size-l);
border-radius: var(--wa-corners-1x);
}
/*
@@ -371,45 +312,15 @@ export default css`
*/
.button--pill.button--small {
border-radius: var(--sl-input-height-small);
border-radius: var(--wa-corners-pill);
}
.button--pill.button--medium {
border-radius: var(--sl-input-height-medium);
border-radius: var(--wa-corners-pill);
}
.button--pill.button--large {
border-radius: var(--sl-input-height-large);
}
/*
* Circle modifier
*/
.button--circle {
padding-left: 0;
padding-right: 0;
}
.button--circle.button--small {
width: var(--sl-input-height-small);
border-radius: 50%;
}
.button--circle.button--medium {
width: var(--sl-input-height-medium);
border-radius: 50%;
}
.button--circle.button--large {
width: var(--sl-input-height-large);
border-radius: 50%;
}
.button--circle .button__prefix,
.button--circle .button__suffix,
.button--circle .button__caret {
display: none;
border-radius: var(--wa-corners-pill);
}
/*
@@ -442,6 +353,7 @@ export default css`
.button--loading sl-spinner {
--indicator-color: currentColor;
--track-color: color-mix(in oklch, currentColor, transparent 90%);
position: absolute;
font-size: 1em;
height: 1em;
@@ -473,69 +385,69 @@ export default css`
*/
.button--has-label.button--small .button__label {
padding: 0 var(--sl-spacing-small);
padding: var(--wa-space-xs) var(--wa-space-m);
}
.button--has-label.button--medium .button__label {
padding: 0 var(--sl-spacing-medium);
padding: var(--wa-space-s) var(--wa-space-l);
}
.button--has-label.button--large .button__label {
padding: 0 var(--sl-spacing-large);
padding: var(--wa-space-m) var(--wa-space-xl);
}
.button--has-prefix.button--small {
padding-inline-start: var(--sl-spacing-x-small);
padding-inline-start: var(--wa-space-xs);
}
.button--has-prefix.button--small .button__label {
padding-inline-start: var(--sl-spacing-x-small);
padding-inline-start: var(--wa-space-xs);
}
.button--has-prefix.button--medium {
padding-inline-start: var(--sl-spacing-small);
padding-inline-start: var(--wa-space-s);
}
.button--has-prefix.button--medium .button__label {
padding-inline-start: var(--sl-spacing-small);
padding-inline-start: var(--wa-space-s);
}
.button--has-prefix.button--large {
padding-inline-start: var(--sl-spacing-small);
padding-inline-start: var(--wa-space-s);
}
.button--has-prefix.button--large .button__label {
padding-inline-start: var(--sl-spacing-small);
padding-inline-start: var(--wa-space-s);
}
.button--has-suffix.button--small,
.button--caret.button--small {
padding-inline-end: var(--sl-spacing-x-small);
padding-inline-end: var(--wa-space-xs);
}
.button--has-suffix.button--small .button__label,
.button--caret.button--small .button__label {
padding-inline-end: var(--sl-spacing-x-small);
padding-inline-end: var(--wa-space-xs);
}
.button--has-suffix.button--medium,
.button--caret.button--medium {
padding-inline-end: var(--sl-spacing-small);
padding-inline-end: var(--wa-space-s);
}
.button--has-suffix.button--medium .button__label,
.button--caret.button--medium .button__label {
padding-inline-end: var(--sl-spacing-small);
padding-inline-end: var(--wa-space-s);
}
.button--has-suffix.button--large,
.button--caret.button--large {
padding-inline-end: var(--sl-spacing-small);
padding-inline-end: var(--wa-space-s);
}
.button--has-suffix.button--large .button__label,
.button--caret.button--large .button__label {
padding-inline-end: var(--sl-spacing-small);
padding-inline-end: var(--wa-space-s);
}
/*
@@ -561,17 +473,11 @@ export default css`
/* All except the first */
:host(.sl-button-group__button:not(.sl-button-group__button--first)) {
margin-inline-start: calc(-1 * var(--sl-input-border-width));
margin-inline-start: calc(-1 * var(--wa-border-width-thin));
}
/* Add a visual separator between solid buttons */
:host(
.sl-button-group__button:not(
.sl-button-group__button--first,
.sl-button-group__button--radio,
[variant='default']
):not(:hover)
)
:host(.sl-button-group__button:not(.sl-button-group__button--first, .sl-button-group__button--radio):not(:hover))
.button:after {
content: '';
position: absolute;

View File

@@ -4,7 +4,7 @@ import { runFormControlBaseTests } from '../../internal/test/form-control-base-t
import sinon from 'sinon';
import type SlButton from './button.js';
const variants = ['default', 'primary', 'success', 'neutral', 'warning', 'danger'];
const variants = ['brand', 'success', 'neutral', 'warning', 'danger'];
describe('<sl-button>', () => {
describe('accessibility tests', () => {
@@ -33,7 +33,6 @@ describe('<sl-button>', () => {
expect(el.loading).to.equal(false);
expect(el.outline).to.equal(false);
expect(el.pill).to.equal(false);
expect(el.circle).to.equal(false);
});
it('should render as a <button>', async () => {

View File

@@ -31,7 +31,7 @@ export default class SlTag extends ShoelaceElement {
private readonly localize = new LocalizeController(this);
/** The tag's theme variant. */
@property({ reflect: true }) variant: 'primary' | 'success' | 'neutral' | 'warning' | 'danger' | 'text' = 'neutral';
@property({ reflect: true }) variant: 'brand' | 'success' | 'neutral' | 'warning' | 'danger' | 'text' = 'neutral';
/** The tag's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@@ -54,7 +54,7 @@ export default class SlTag extends ShoelaceElement {
tag: true,
// Types
'tag--primary': this.variant === 'primary',
'tag--brand': this.variant === 'brand',
'tag--success': this.variant === 'success',
'tag--neutral': this.variant === 'neutral',
'tag--warning': this.variant === 'warning',

View File

@@ -26,13 +26,13 @@ export default css`
* Variant modifiers
*/
.tag--primary {
.tag--brand {
background-color: var(--wa-color-brand-container-fill-muted);
border-color: var(--wa-color-brand-element-outline-muted);
color: var(--wa-color-brand-text-on-muted);
}
.tag--primary:active > sl-icon-button {
.tag--brand:active > sl-icon-button {
color: var(--wa-color-brand-text-on-muted);
}