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: 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 ♿️ - Built with accessibility in mind ♿️
- Open source 😸 - 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 ## License
Shoelace is designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska). Its available under the terms of the MIT license. Shoelace is 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! 🥾

View File

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

View File

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

View File

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

View File

@@ -95,9 +95,9 @@ Theme buttons are supported through the button's `variant` attribute.
```html:preview ```html:preview
<sl-button-group label="Alignment"> <sl-button-group label="Alignment">
<sl-button variant="primary">Left</sl-button> <sl-button variant="brand">Left</sl-button>
<sl-button variant="primary">Center</sl-button> <sl-button variant="brand">Center</sl-button>
<sl-button variant="primary">Right</sl-button> <sl-button variant="brand">Right</sl-button>
</sl-button-group> </sl-button-group>
<br /><br /> <br /><br />
@@ -111,9 +111,9 @@ Theme buttons are supported through the button's `variant` attribute.
<br /><br /> <br /><br />
<sl-button-group label="Alignment"> <sl-button-group label="Alignment">
<sl-button variant="neutral">Left</sl-button> <sl-button>Left</sl-button>
<sl-button variant="neutral">Center</sl-button> <sl-button>Center</sl-button>
<sl-button variant="neutral">Right</sl-button> <sl-button>Right</sl-button>
</sl-button-group> </sl-button-group>
<br /><br /> <br /><br />
@@ -140,9 +140,9 @@ import SlButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
const App = () => ( const App = () => (
<> <>
<SlButtonGroup label="Alignment"> <SlButtonGroup label="Alignment">
<SlButton variant="primary">Left</SlButton> <SlButton variant="brand">Left</SlButton>
<SlButton variant="primary">Center</SlButton> <SlButton variant="brand">Center</SlButton>
<SlButton variant="primary">Right</SlButton> <SlButton variant="brand">Right</SlButton>
</SlButtonGroup> </SlButtonGroup>
<br /> <br />
@@ -158,9 +158,9 @@ const App = () => (
<br /> <br />
<SlButtonGroup label="Alignment"> <SlButtonGroup label="Alignment">
<SlButton variant="neutral">Left</SlButton> <SlButton>Left</SlButton>
<SlButton variant="neutral">Center</SlButton> <SlButton>Center</SlButton>
<SlButton variant="neutral">Right</SlButton> <SlButton>Right</SlButton>
</SlButtonGroup> </SlButtonGroup>
<br /> <br />
@@ -313,9 +313,9 @@ Create a split button using a button and a dropdown. Use a [visually hidden](/co
```html:preview ```html:preview
<sl-button-group label="Example Button Group"> <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-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-visually-hidden>More options</sl-visually-hidden>
</sl-button> </sl-button>
<sl-menu> <sl-menu>
@@ -336,9 +336,9 @@ import SlMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
const App = () => ( const App = () => (
<SlButtonGroup label="Example Button Group"> <SlButtonGroup label="Example Button Group">
<SlButton variant="primary">Save</SlButton> <SlButton variant="brand">Save</SlButton>
<SlDropdown placement="bottom-end"> <SlDropdown placement="bottom-end">
<SlButton slot="trigger" variant="primary" caret></SlButton> <SlButton slot="trigger" variant="brand" caret></SlButton>
<SlMenu> <SlMenu>
<SlMenuItem>Save</SlMenuItem> <SlMenuItem>Save</SlMenuItem>
<SlMenuItem>Save as&hellip;</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. Use the `variant` attribute to set the button's variant.
```html:preview ```html:preview
<sl-button variant="default">Default</sl-button> <sl-button variant="brand">Brand</sl-button>
<sl-button variant="primary">Primary</sl-button>
<sl-button variant="success">Success</sl-button> <sl-button variant="success">Success</sl-button>
<sl-button variant="neutral">Neutral</sl-button> <sl-button variant="neutral">Neutral</sl-button>
<sl-button variant="warning">Warning</sl-button> <sl-button variant="warning">Warning</sl-button>
@@ -35,8 +34,7 @@ import SlButton from '@shoelace-style/shoelace/dist/react/button';
const App = () => ( const App = () => (
<> <>
<SlButton variant="default">Default</SlButton> <SlButton variant="brand">Brand</SlButton>
<SlButton variant="primary">Primary</SlButton>
<SlButton variant="success">Success</SlButton> <SlButton variant="success">Success</SlButton>
<SlButton variant="neutral">Neutral</SlButton> <SlButton variant="neutral">Neutral</SlButton>
<SlButton variant="warning">Warning</SlButton> <SlButton variant="warning">Warning</SlButton>
@@ -72,8 +70,7 @@ const App = () => (
Use the `outline` attribute to draw outlined buttons with transparent backgrounds. Use the `outline` attribute to draw outlined buttons with transparent backgrounds.
```html:preview ```html:preview
<sl-button variant="default" outline>Default</sl-button> <sl-button variant="brand" outline>Brand</sl-button>
<sl-button variant="primary" outline>Primary</sl-button>
<sl-button variant="success" outline>Success</sl-button> <sl-button variant="success" outline>Success</sl-button>
<sl-button variant="neutral" outline>Neutral</sl-button> <sl-button variant="neutral" outline>Neutral</sl-button>
<sl-button variant="warning" outline>Warning</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 = () => ( const App = () => (
<> <>
<SlButton variant="default" outline> <SlButton variant="brand" outline>
Default Brand
</SlButton>
<SlButton variant="primary" outline>
Primary
</SlButton> </SlButton>
<SlButton variant="success" outline> <SlButton variant="success" outline>
Success 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 ### 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. 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. 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 ```html:preview
<sl-button variant="default" size="small" style="width: 100%; margin-bottom: 1rem;">Small</sl-button> <sl-button 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 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="large" style="width: 100%;">Large</sl-button>
``` ```
{% raw %} {% raw %}
@@ -251,13 +208,13 @@ import SlButton from '@shoelace-style/shoelace/dist/react/button';
const App = () => ( const App = () => (
<> <>
<SlButton variant="default" size="small" style={{ width: '100%', marginBottom: '1rem' }}> <SlButton size="small" style={{ width: '100%', marginBottom: '1rem' }}>
Small Small
</SlButton> </SlButton>
<SlButton variant="default" size="medium" style={{ width: '100%', marginBottom: '1rem' }}> <SlButton size="medium" style={{ width: '100%', marginBottom: '1rem' }}>
Medium Medium
</SlButton> </SlButton>
<SlButton variant="default" size="large" style={{ width: '100%' }}> <SlButton size="large" style={{ width: '100%' }}>
Large Large
</SlButton> </SlButton>
</> </>
@@ -271,17 +228,17 @@ const App = () => (
Use the `prefix` and `suffix` slots to add icons. Use the `prefix` and `suffix` slots to add icons.
```html:preview ```html:preview
<sl-button variant="default" size="small"> <sl-button size="small">
<sl-icon slot="prefix" name="gear"></sl-icon> <sl-icon slot="prefix" name="gear"></sl-icon>
Settings Settings
</sl-button> </sl-button>
<sl-button variant="default" size="small"> <sl-button size="small">
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon> <sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh Refresh
</sl-button> </sl-button>
<sl-button variant="default" size="small"> <sl-button size="small">
<sl-icon slot="prefix" name="link-45deg"></sl-icon> <sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon> <sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open Open
@@ -289,17 +246,17 @@ Use the `prefix` and `suffix` slots to add icons.
<br /><br /> <br /><br />
<sl-button variant="default"> <sl-button>
<sl-icon slot="prefix" name="gear"></sl-icon> <sl-icon slot="prefix" name="gear"></sl-icon>
Settings Settings
</sl-button> </sl-button>
<sl-button variant="default"> <sl-button>
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon> <sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh Refresh
</sl-button> </sl-button>
<sl-button variant="default"> <sl-button>
<sl-icon slot="prefix" name="link-45deg"></sl-icon> <sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon> <sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open Open
@@ -307,17 +264,17 @@ Use the `prefix` and `suffix` slots to add icons.
<br /><br /> <br /><br />
<sl-button variant="default" size="large"> <sl-button size="large">
<sl-icon slot="prefix" name="gear"></sl-icon> <sl-icon slot="prefix" name="gear"></sl-icon>
Settings Settings
</sl-button> </sl-button>
<sl-button variant="default" size="large"> <sl-button size="large">
<sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon> <sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
Refresh Refresh
</sl-button> </sl-button>
<sl-button variant="default" size="large"> <sl-button size="large">
<sl-icon slot="prefix" name="link-45deg"></sl-icon> <sl-icon slot="prefix" name="link-45deg"></sl-icon>
<sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon> <sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
Open Open
@@ -330,17 +287,17 @@ import SlIcon from '@shoelace-style/shoelace/dist/react/icon';
const App = () => ( const App = () => (
<> <>
<SlButton variant="default" size="small"> <SlButton size="small">
<SlIcon slot="prefix" name="gear"></SlIcon> <SlIcon slot="prefix" name="gear"></SlIcon>
Settings Settings
</SlButton> </SlButton>
<SlButton variant="default" size="small"> <SlButton size="small">
<SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon> <SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
Refresh Refresh
</SlButton> </SlButton>
<SlButton variant="default" size="small"> <SlButton size="small">
<SlIcon slot="prefix" name="link-45deg"></SlIcon> <SlIcon slot="prefix" name="link-45deg"></SlIcon>
<SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon> <SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
Open Open
@@ -349,17 +306,17 @@ const App = () => (
<br /> <br />
<br /> <br />
<SlButton variant="default"> <SlButton>
<SlIcon slot="prefix" name="gear"></SlIcon> <SlIcon slot="prefix" name="gear"></SlIcon>
Settings Settings
</SlButton> </SlButton>
<SlButton variant="default"> <SlButton>
<SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon> <SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
Refresh Refresh
</SlButton> </SlButton>
<SlButton variant="default"> <SlButton>
<SlIcon slot="prefix" name="link-45deg"></SlIcon> <SlIcon slot="prefix" name="link-45deg"></SlIcon>
<SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon> <SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
Open Open
@@ -368,17 +325,17 @@ const App = () => (
<br /> <br />
<br /> <br />
<SlButton variant="default" size="large"> <SlButton size="large">
<SlIcon slot="prefix" name="gear"></SlIcon> <SlIcon slot="prefix" name="gear"></SlIcon>
Settings Settings
</SlButton> </SlButton>
<SlButton variant="default" size="large"> <SlButton size="large">
<SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon> <SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
Refresh Refresh
</SlButton> </SlButton>
<SlButton variant="default" size="large"> <SlButton size="large">
<SlIcon slot="prefix" name="link-45deg"></SlIcon> <SlIcon slot="prefix" name="link-45deg"></SlIcon>
<SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon> <SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
Open 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. 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 ```html:preview
<sl-button variant="default" loading>Default</sl-button> <sl-button variant="brand" loading>Brand</sl-button>
<sl-button variant="primary" loading>Primary</sl-button>
<sl-button variant="success" loading>Success</sl-button> <sl-button variant="success" loading>Success</sl-button>
<sl-button variant="neutral" loading>Neutral</sl-button> <sl-button variant="neutral" loading>Neutral</sl-button>
<sl-button variant="warning" loading>Warning</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 = () => ( const App = () => (
<> <>
<SlButton variant="default" loading> <SlButton variant="brand" loading>
Default Brand
</SlButton>
<SlButton variant="primary" loading>
Primary
</SlButton> </SlButton>
<SlButton variant="success" loading> <SlButton variant="success" loading>
Success Success
@@ -460,8 +413,7 @@ const App = () => (
Use the `disabled` attribute to disable a button. Use the `disabled` attribute to disable a button.
```html:preview ```html:preview
<sl-button variant="default" disabled>Default</sl-button> <sl-button variant="brand" disabled>Brand</sl-button>
<sl-button variant="primary" disabled>Primary</sl-button>
<sl-button variant="success" disabled>Success</sl-button> <sl-button variant="success" disabled>Success</sl-button>
<sl-button variant="neutral" disabled>Neutral</sl-button> <sl-button variant="neutral" disabled>Neutral</sl-button>
<sl-button variant="warning" disabled>Warning</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 = () => ( const App = () => (
<> <>
<SlButton variant="default" disabled> <SlButton variant="brand" disabled>
Default Brand
</SlButton>
<SlButton variant="primary" disabled>
Primary
</SlButton> </SlButton>
<SlButton variant="success" disabled> <SlButton variant="success" disabled>
@@ -502,18 +450,15 @@ const App = () => (
### Styling Buttons ### 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 ```html:preview
<sl-button class="pink">Pink Button</sl-button> <sl-button class="pink">Pink Button</sl-button>
<style> <style>
sl-button.pink::part(base) { sl-button.pink::part(base) {
/* Set design tokens for height and border width */ border-radius: 6px;
--sl-input-height-medium: 48px; border: solid 2px;
--sl-input-border-width: 4px;
border-radius: 0;
background-color: #ff1493; background-color: #ff1493;
border-top-color: #ff7ac1; border-top-color: #ff7ac1;
border-left-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; color: white;
font-size: 1.125rem; font-size: 1.125rem;
box-shadow: 0 2px 10px #0002; 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 { sl-button.pink::part(base):hover {
transform: scale(1.05) rotate(-1deg); transform: scale(1.05);
} }
sl-button.pink::part(base):active { 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-right-color: #ff7ac1;
border-bottom-color: #ff7ac1; border-bottom-color: #ff7ac1;
border-left-color: #ad005c; border-left-color: #ad005c;
transform: scale(1.05) rotate(-1deg) translateY(2px); transform: translateY(1px);
} }
sl-button.pink::part(base):focus-visible { sl-button.pink::part(base):focus-visible {

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ The mutation observer will report changes to the content it wraps through the `s
```html:preview ```html:preview
<div class="mutation-overview"> <div class="mutation-overview">
<sl-mutation-observer attr="variant"> <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> </sl-mutation-observer>
<br /> <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 container = document.querySelector('.mutation-overview');
const mutationObserver = container.querySelector('sl-mutation-observer'); const mutationObserver = container.querySelector('sl-mutation-observer');
const button = container.querySelector('sl-button'); const button = container.querySelector('sl-button');
const variants = ['primary', 'success', 'neutral', 'warning', 'danger']; const variants = ['brand', 'success', 'neutral', 'warning', 'danger'];
let clicks = 0; let clicks = 0;
// Change the button's variant attribute // 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; let clicks = 0;
const App = () => { const App = () => {
const [variant, setVariant] = useState('primary'); const [variant, setVariant] = useState('brand');
function handleClick() { function handleClick() {
clicks++; 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"> <div class="mutation-child-list">
<sl-mutation-observer child-list> <sl-mutation-observer child-list>
<div class="buttons"> <div class="buttons">
<sl-button variant="primary">Add button</sl-button> <sl-button variant="brand">Add button</sl-button>
</div> </div>
</sl-mutation-observer> </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 container = document.querySelector('.mutation-child-list');
const mutationObserver = container.querySelector('sl-mutation-observer'); const mutationObserver = container.querySelector('sl-mutation-observer');
const buttons = container.querySelector('.buttons'); const buttons = container.querySelector('.buttons');
const button = container.querySelector('sl-button[variant="primary"]'); const button = container.querySelector('sl-button[variant="brand"]');
let i = 0; let i = 0;
// Add a button // 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 // Remove a button
buttons.addEventListener('click', event => { 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(); event.stopPropagation();
if (target) { if (target) {
@@ -175,7 +175,7 @@ const App = () => {
<div className="mutation-child-list"> <div className="mutation-child-list">
<SlMutationObserver child-list onSlMutation={event => console.log(event.detail)}> <SlMutationObserver child-list onSlMutation={event => console.log(event.detail)}>
<div className="buttons"> <div className="buttons">
<SlButton variant="primary" onClick={addButton}> <SlButton variant="brand" onClick={addButton}>
Add button Add button
</SlButton> </SlButton>
{buttonIds.map(id => ( {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 value="3">Option 3</sl-radio>
</sl-radio-group> </sl-radio-group>
<br /> <br />
<sl-button type="submit" variant="primary">Submit</sl-button> <sl-button type="submit" variant="brand">Submit</sl-button>
</form> </form>
<script> <script>
@@ -206,7 +206,7 @@ const App = () => {
</SlRadio> </SlRadio>
</SlRadioGroup> </SlRadioGroup>
<br /> <br />
<SlButton type="submit" variant="primary"> <SlButton type="submit" variant="brand">
Submit Submit
</SlButton> </SlButton>
</form> </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 value="3">Choose me</sl-radio>
</sl-radio-group> </sl-radio-group>
<br /> <br />
<sl-button type="submit" variant="primary">Submit</sl-button> <sl-button type="submit" variant="brand">Submit</sl-button>
</form> </form>
<script> <script>
@@ -284,7 +284,7 @@ const App = () => {
<SlRadio value="3">Choose me</SlRadio> <SlRadio value="3">Choose me</SlRadio>
</SlRadioGroup> </SlRadioGroup>
<br /> <br />
<SlButton type="submit" variant="primary"> <SlButton type="submit" variant="brand">
Submit Submit
</SlButton> </SlButton>
</form> </form>

View File

@@ -6,7 +6,7 @@ layout: component
--- ---
```html:preview ```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="success">Success</sl-tag>
<sl-tag variant="neutral">Neutral</sl-tag> <sl-tag variant="neutral">Neutral</sl-tag>
<sl-tag variant="warning">Warning</sl-tag> <sl-tag variant="warning">Warning</sl-tag>
@@ -18,7 +18,7 @@ import SlTag from '@shoelace-style/shoelace/dist/react/tag';
const App = () => ( const App = () => (
<> <>
<SlTag variant="primary">Primary</SlTag> <SlTag variant="brand">Brand</SlTag>
<SlTag variant="success">Success</SlTag> <SlTag variant="success">Success</SlTag>
<SlTag variant="neutral">Neutral</SlTag> <SlTag variant="neutral">Neutral</SlTag>
<SlTag variant="warning">Warning</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 ```jsx
import SlButton from '@shoelace-style/shoelace/%NPMDIR%/react/button'; 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; 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"> <sl-drawer label="Drawer" placement="start" class="drawer-placement-start" :open="drawerIsOpen">
This drawer slides in from the start. This drawer slides in from the start.
<div slot="footer"> <div slot="footer">
<sl-button variant="primary" @click=" drawerIsOpen = false">Close</sl-button> <sl-button variant="brand" @click=" drawerIsOpen = false">Close</sl-button>
</div> </div>
</sl-drawer> </sl-drawer>
``` ```

View File

@@ -75,7 +75,7 @@ The form will not be submitted if a required field is incomplete.
<br /> <br />
<sl-checkbox required>Check me before submitting</sl-checkbox> <sl-checkbox required>Check me before submitting</sl-checkbox>
<br /><br /> <br /><br />
<sl-button type="submit" variant="primary">Submit</sl-button> <sl-button type="submit" variant="brand">Submit</sl-button>
</form> </form>
<script type="module"> <script type="module">
@@ -128,7 +128,7 @@ const App = () => {
<SlCheckbox required>Check me before submitting</SlCheckbox> <SlCheckbox required>Check me before submitting</SlCheckbox>
<br /> <br />
<br /> <br />
<SlButton type="submit" variant="primary"> <SlButton type="submit" variant="brand">
Submit Submit
</SlButton> </SlButton>
</form> </form>
@@ -144,7 +144,7 @@ To restrict a value to a specific [pattern](https://developer.mozilla.org/en-US/
<form class="input-validation-pattern"> <form class="input-validation-pattern">
<sl-input name="letters" required label="Letters" pattern="[A-Za-z]+"></sl-input> <sl-input name="letters" required label="Letters" pattern="[A-Za-z]+"></sl-input>
<br /> <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> <sl-button type="reset" variant="default">Reset</sl-button>
</form> </form>
@@ -178,7 +178,7 @@ const App = () => {
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<SlInput name="letters" required label="Letters" pattern="[A-Za-z]+" /> <SlInput name="letters" required label="Letters" pattern="[A-Za-z]+" />
<br /> <br />
<SlButton type="submit" variant="primary"> <SlButton type="submit" variant="brand">
Submit Submit
</SlButton> </SlButton>
</form> </form>
@@ -196,7 +196,7 @@ Some input types will automatically trigger constraints, such as `email` and `ur
<br /> <br />
<sl-input type="url" label="URL" placeholder="https://example.com/" required></sl-input> <sl-input type="url" label="URL" placeholder="https://example.com/" required></sl-input>
<br /> <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> <sl-button type="reset" variant="default">Reset</sl-button>
</form> </form>
@@ -232,7 +232,7 @@ const App = () => {
<br /> <br />
<SlInput type="url" label="URL" placeholder="https://example.com/" required /> <SlInput type="url" label="URL" placeholder="https://example.com/" required />
<br /> <br />
<SlButton type="submit" variant="primary"> <SlButton type="submit" variant="brand">
Submit Submit
</SlButton> </SlButton>
</form> </form>
@@ -248,7 +248,7 @@ To create a custom validation error, pass a non-empty string to the `setCustomVa
<form class="input-validation-custom"> <form class="input-validation-custom">
<sl-input label="Type “shoelace”" required></sl-input> <sl-input label="Type “shoelace”" required></sl-input>
<br /> <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> <sl-button type="reset" variant="default">Reset</sl-button>
</form> </form>
@@ -305,7 +305,7 @@ const App = () => {
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<SlInput ref={input} label="Type 'shoelace'" required value={value} onSlInput={handleInput} /> <SlInput ref={input} label="Type 'shoelace'" required value={value} onSlInput={handleInput} />
<br /> <br />
<SlButton type="submit" variant="primary"> <SlButton type="submit" variant="brand">
Submit Submit
</SlButton> </SlButton>
</form> </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-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> <sl-button type="reset" variant="default">Reset</sl-button>
</form> </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> <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> <sl-button type="reset" variant="default">Reset</sl-button>
</form> </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. ⛷ 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 ## Attribution
Special thanks to the following projects and individuals that help make Shoelace possible. Special thanks to the following projects and individuals that help make Shoelace possible.

View File

@@ -6,12 +6,18 @@ meta:
# Changelog # 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. 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). 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 ## Next
- Fixed a bug in `<sl-switch>` that resulted in improper spacing between the label and the required asterisk [#1540] - 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 - Show the community what you're working on
- Learn more about the project, its values, and its roadmap - 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> <sl-icon name="github" slot="prefix"></sl-icon>
Join the Discussion Join the Discussion
</sl-button> </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 - Show the community what you're working on
- Chat live with other designers, developers, and Shoelace fans - 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> <sl-icon name="discord" slot="prefix"></sl-icon>
Join the Chat Join the Chat
</sl-button> </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. 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> <sl-icon name="stack-overflow" slot="prefix"></sl-icon>
Ask for Help Ask for Help
</sl-button> </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. **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> <sl-icon name="twitter" slot="prefix"></sl-icon>
Follow on Twitter Follow on Twitter
</sl-button> </sl-button>

View File

@@ -3,7 +3,7 @@
"description": "A forward-thinking library of web components.", "description": "A forward-thinking library of web components.",
"version": "2.8.0", "version": "2.8.0",
"homepage": "https://github.com/shoelace-style/shoelace", "homepage": "https://github.com/shoelace-style/shoelace",
"author": "Cory LaViska", "author": "Web Awesome",
"license": "MIT", "license": "MIT",
"customElements": "dist/custom-elements.json", "customElements": "dist/custom-elements.json",
"web-types": "./web-types.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; @property({ type: Boolean, reflect: true }) closable = false;
/** The alert's theme variant. */ /** 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 * 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--open': this.open,
'alert--closable': this.closable, 'alert--closable': this.closable,
'alert--has-icon': this.hasSlotController.test('icon'), 'alert--has-icon': this.hasSlotController.test('icon'),
'alert--primary': this.variant === 'primary', 'alert--brand': this.variant === 'brand',
'alert--success': this.variant === 'success', 'alert--success': this.variant === 'success',
'alert--neutral': this.variant === 'neutral', 'alert--neutral': this.variant === 'neutral',
'alert--warning': this.variant === 'warning', 'alert--warning': this.variant === 'warning',

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,9 +25,9 @@ describe('<sl-badge>', () => {
expect(el.innerText).to.eq('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"]')!; 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', () => { it('should append the pill class to the classlist to render a pill', () => {
const part = el.shadowRoot!.querySelector('[part~="base"]')!; 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', () => { it('should append the pulse class to the classlist to render a pulse', () => {
const part = el.shadowRoot!.querySelector('[part~="base"]')!; 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}`, () => { describe(`when passed a variant attribute ${variant}`, () => {
before(async () => { before(async () => {
el = await fixture<SlBadge>(html`<sl-badge variant="${variant}">Badge</sl-badge>`); 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 }); 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"]')!; const part = el.shadowRoot!.querySelector('[part~="base"]')!;
expect(part.classList.value.trim()).to.eq(`badge badge--${variant}`); 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 @property() title = ''; // make reactive to pass through
/** The button's theme variant. */ /** The button's theme variant. */
@property({ reflect: true }) variant: 'default' | 'primary' | 'success' | 'neutral' | 'warning' | 'danger' | 'text' = @property({ reflect: true }) variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'text' = 'neutral';
'default';
/** The button's size. */ /** The button's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium'; @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. */ /** Draws a pill-style button with rounded edges. */
@property({ type: Boolean, reflect: true }) pill = false; @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 * 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. * `<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'); this.emit('sl-focus');
} }
private handleClick() { private handleClick(event: MouseEvent) {
if (this.type === 'submit') { if (this.type === 'submit') {
this.formControlController.submit(this); this.formControlController.submit(this);
} }
@@ -195,6 +188,10 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
if (this.type === 'reset') { if (this.type === 'reset') {
this.formControlController.reset(this); this.formControlController.reset(this);
} }
if (this.href) {
event.preventDefault();
}
} }
private handleInvalid(event: Event) { private handleInvalid(event: Event) {
@@ -275,8 +272,7 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
part="base" part="base"
class=${classMap({ class=${classMap({
button: true, button: true,
'button--default': this.variant === 'default', 'button--brand': this.variant === 'brand',
'button--primary': this.variant === 'primary',
'button--success': this.variant === 'success', 'button--success': this.variant === 'success',
'button--neutral': this.variant === 'neutral', 'button--neutral': this.variant === 'neutral',
'button--warning': this.variant === 'warning', 'button--warning': this.variant === 'warning',
@@ -286,7 +282,6 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
'button--medium': this.size === 'medium', 'button--medium': this.size === 'medium',
'button--large': this.size === 'large', 'button--large': this.size === 'large',
'button--caret': this.caret, 'button--caret': this.caret,
'button--circle': this.circle,
'button--disabled': this.disabled, 'button--disabled': this.disabled,
'button--focused': this.hasFocus, 'button--focused': this.hasFocus,
'button--loading': this.loading, 'button--loading': this.loading,

View File

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

View File

@@ -4,7 +4,7 @@ import { runFormControlBaseTests } from '../../internal/test/form-control-base-t
import sinon from 'sinon'; import sinon from 'sinon';
import type SlButton from './button.js'; 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('<sl-button>', () => {
describe('accessibility tests', () => { describe('accessibility tests', () => {
@@ -33,7 +33,6 @@ describe('<sl-button>', () => {
expect(el.loading).to.equal(false); expect(el.loading).to.equal(false);
expect(el.outline).to.equal(false); expect(el.outline).to.equal(false);
expect(el.pill).to.equal(false); expect(el.pill).to.equal(false);
expect(el.circle).to.equal(false);
}); });
it('should render as a <button>', async () => { 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); private readonly localize = new LocalizeController(this);
/** The tag's theme variant. */ /** 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. */ /** The tag's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium'; @property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@@ -54,7 +54,7 @@ export default class SlTag extends ShoelaceElement {
tag: true, tag: true,
// Types // Types
'tag--primary': this.variant === 'primary', 'tag--brand': this.variant === 'brand',
'tag--success': this.variant === 'success', 'tag--success': this.variant === 'success',
'tag--neutral': this.variant === 'neutral', 'tag--neutral': this.variant === 'neutral',
'tag--warning': this.variant === 'warning', 'tag--warning': this.variant === 'warning',

View File

@@ -26,13 +26,13 @@ export default css`
* Variant modifiers * Variant modifiers
*/ */
.tag--primary { .tag--brand {
background-color: var(--wa-color-brand-container-fill-muted); background-color: var(--wa-color-brand-container-fill-muted);
border-color: var(--wa-color-brand-element-outline-muted); border-color: var(--wa-color-brand-element-outline-muted);
color: var(--wa-color-brand-text-on-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); color: var(--wa-color-brand-text-on-muted);
} }