diff --git a/docs/components/button.md b/docs/components/button.md
index bc113677..544f12c2 100644
--- a/docs/components/button.md
+++ b/docs/components/button.md
@@ -91,6 +91,24 @@ As expected, buttons can be given a custom width by setting its `width`. This is
Use the `prefix` and `suffix` slots to add icons.
```html preview
+
+
+ Settings
+
+
+
+
+ Refresh
+
+
+
+
+
+ Open
+
+
+
+
Settings
@@ -106,6 +124,24 @@ Use the `prefix` and `suffix` slots to add icons.
Open
+
+
+
+
+
+ Settings
+
+
+
+
+ Refresh
+
+
+
+
+
+ Open
+
```
### Caret
@@ -144,4 +180,22 @@ Use the `disabled` prop to disable a button. Clicks will be suppressed until the
Danger
```
+### Split Buttons
+
+Create a split button using a [button group](/components/button-group) and a [dropdown](/components/dropdown).
+
+```html preview
+
+ Save
+
+
+
+ Save
+ Save as…
+ Save all
+
+
+
+```
+
[component-metadata:sl-button]
diff --git a/docs/getting-started/changelog.md b/docs/getting-started/changelog.md
index e5cc0e44..7e09f249 100644
--- a/docs/getting-started/changelog.md
+++ b/docs/getting-started/changelog.md
@@ -25,6 +25,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
- Fixed a bug where `sl-color-picker` preview wouldn't update in Safari
- Fixed a bug where removing an icon's `name` or `src` wouldn't remove the previously rendered SVG [#285](https://github.com/shoelace-style/shoelace/issues/285)
- Fixed a bug where disabled link buttons didn't appear disabled
+- Improved button spacings and added split button example
- Improved elevation tokens in dark theme
- Improved accessibility in `sl-tooltip` by allowing escape to dismiss it [#219](https://github.com/shoelace-style/shoelace/issues/219)
- Improved slot detection in `sl-card`, `sl-dialog`, and `sl-drawer`
diff --git a/src/components/button/button.scss b/src/components/button/button.scss
index d9249446..d22bdc4b 100644
--- a/src/components/button/button.scss
+++ b/src/components/button/button.scss
@@ -19,6 +19,7 @@
user-select: none;
white-space: nowrap;
vertical-align: middle;
+ padding: 0;
transition: var(--sl-transition-fast) background-color, var(--sl-transition-fast) color,
var(--sl-transition-fast) border, var(--sl-transition-fast) box-shadow;
cursor: inherit;
@@ -55,13 +56,13 @@
}
.button__prefix ::slotted(:first-child) {
- margin-left: calc(-1 * var(--sl-spacing-x-small));
- margin-right: var(--sl-spacing-x-small);
+ // margin-left: calc(-1 * var(--sl-spacing-x-small));
+ // margin-right: var(--sl-spacing-x-small);
}
.button__suffix ::slotted(:last-child) {
- margin-left: var(--sl-spacing-x-small);
- margin-right: calc(-1 * var(--sl-spacing-x-small));
+ // margin-left: var(--sl-spacing-x-small);
+ // margin-right: calc(-1 * var(--sl-spacing-x-small));
}
.button__label {
@@ -264,7 +265,6 @@
height: var(--sl-input-height-small);
line-height: calc(var(--sl-input-height-small) - var(--sl-input-border-width) * 2);
border-radius: var(--sl-input-border-radius-small);
- padding: 0 var(--sl-spacing-medium);
}
.button--medium {
@@ -272,7 +272,6 @@
height: var(--sl-input-height-medium);
line-height: calc(var(--sl-input-height-medium) - var(--sl-input-border-width) * 2);
border-radius: var(--sl-input-border-radius-medium);
- padding: 0 var(--sl-spacing-large);
}
.button--large {
@@ -280,7 +279,6 @@
height: var(--sl-input-height-large);
line-height: calc(var(--sl-input-height-large) - var(--sl-input-border-width) * 2);
border-radius: var(--sl-input-border-radius-large);
- padding: 0 var(--sl-spacing-x-large);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -343,8 +341,6 @@
.button__caret {
display: flex;
align-items: center;
- margin-left: var(--sl-spacing-xx-small);
- margin-right: calc(-1 * var(--sl-spacing-xx-small));
svg {
width: 1em;
@@ -389,3 +385,74 @@
transform: translateY(-50%) translateX(50%);
pointer-events: none;
}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Button spacing
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+.button--has-label {
+ &.button--small .button__label {
+ padding: 0 var(--sl-spacing-small);
+ }
+
+ &.button--medium .button__label {
+ padding: 0 var(--sl-spacing-medium);
+ }
+
+ &.button--large .button__label {
+ padding: 0 var(--sl-spacing-large);
+ }
+}
+
+.button--has-prefix {
+ &.button--small {
+ padding-left: var(--sl-spacing-x-small);
+
+ .button__label {
+ padding-left: var(--sl-spacing-x-small);
+ }
+ }
+
+ &.button--medium {
+ padding-left: var(--sl-spacing-small);
+
+ .button__label {
+ padding-left: var(--sl-spacing-small);
+ }
+ }
+
+ &.button--large {
+ padding-left: var(--sl-spacing-small);
+
+ .button__label {
+ padding-left: var(--sl-spacing-small);
+ }
+ }
+}
+
+.button--has-suffix,
+.button--caret {
+ &.button--small {
+ padding-right: var(--sl-spacing-x-small);
+
+ .button__label {
+ padding-right: var(--sl-spacing-x-small);
+ }
+ }
+
+ &.button--medium {
+ padding-right: var(--sl-spacing-small);
+
+ .button__label {
+ padding-right: var(--sl-spacing-small);
+ }
+ }
+
+ &.button--large {
+ padding-right: var(--sl-spacing-small);
+
+ .button__label {
+ padding-right: var(--sl-spacing-small);
+ }
+ }
+}
diff --git a/src/components/button/button.tsx b/src/components/button/button.tsx
index 65fa62d9..e1411066 100644
--- a/src/components/button/button.tsx
+++ b/src/components/button/button.tsx
@@ -1,4 +1,5 @@
-import { Component, Event, EventEmitter, Method, Prop, State, h } from '@stencil/core';
+import { Component, Element, Event, EventEmitter, Method, Prop, State, h } from '@stencil/core';
+import { hasSlot } from '../../utilities/slot';
/**
* @since 2.0
@@ -23,7 +24,12 @@ import { Component, Event, EventEmitter, Method, Prop, State, h } from '@stencil
export class Button {
button: HTMLButtonElement;
+ @Element() host: HTMLSlButtonElement;
+
@State() hasFocus = false;
+ @State() hasLabel = false;
+ @State() hasPrefix = false;
+ @State() hasSuffix = false;
/** The button's type. */
@Prop({ reflect: true }) type: 'default' | 'primary' | 'success' | 'info' | 'warning' | 'danger' | 'text' = 'default';
@@ -74,6 +80,11 @@ export class Button {
this.handleBlur = this.handleBlur.bind(this);
this.handleFocus = this.handleFocus.bind(this);
this.handleClick = this.handleClick.bind(this);
+ this.handleSlotChange = this.handleSlotChange.bind(this);
+ }
+
+ componentWillLoad() {
+ this.handleSlotChange();
}
/** Sets focus on the button. */
@@ -88,6 +99,12 @@ export class Button {
this.button.blur();
}
+ handleSlotChange() {
+ this.hasLabel = hasSlot(this.host);
+ this.hasPrefix = hasSlot(this.host, 'prefix');
+ this.hasSuffix = hasSlot(this.host, 'suffix');
+ }
+
handleBlur() {
this.hasFocus = false;
this.slBlur.emit();
@@ -137,7 +154,10 @@ export class Button {
'button--disabled': this.disabled,
'button--focused': this.hasFocus,
'button--loading': this.loading,
- 'button--pill': this.pill
+ 'button--pill': this.pill,
+ 'button--has-label': this.hasLabel,
+ 'button--has-prefix': this.hasPrefix,
+ 'button--has-suffix': this.hasSuffix
}}
disabled={isButton ? this.disabled : null}
type={isButton ? (this.submit ? 'submit' : 'button') : null}
@@ -152,13 +172,13 @@ export class Button {
onClick={this.handleClick}
>
-
+
-
+
-
+
{this.caret && (