Add icon button

pull/146/head
Cory LaViska 2020-07-24 16:57:38 -04:00
rodzic 79b84cc47e
commit 96f32122c0
13 zmienionych plików z 210 dodań i 110 usunięć

Wyświetl plik

@ -21,6 +21,7 @@
- [Dropdown](/components/dropdown.md)
- [Form](/components/form.md)
- [Icon](/components/icon.md)
- [Icon Button](/components/icon-button.md)
- [Input](/components/input.md)
- [Menu](/components/menu.md)
- [Menu Divider](/components/menu-divider.md)

Wyświetl plik

@ -0,0 +1,60 @@
# Icon Button
[component-header:sl-icon-button]
Icons buttons are simple, icon-only buttons that can be used for actions and in toolbars.
For a full list of icons that come bundled with Shoelace, refer to the [icon component](/components/icon).
```html preview
<sl-icon-button name="gear"></sl-icon-button>
<sl-icon-button name="sliders"></sl-icon-button>
<sl-icon-button name="x"></sl-icon-button>
```
## Examples
### Sizes
Icon buttons inherit their parent element's `font-size`.
```html preview
<sl-icon-button name="pencil" style="font-size: 1.5rem;"></sl-icon-button>
<sl-icon-button name="pencil" style="font-size: 2rem;"></sl-icon-button>
<sl-icon-button name="pencil" style="font-size: 2.5rem;"></sl-icon-button>
```
### Colors
You can customize icon button's color by styling its `base` part.
```html preview
<sl-icon-button name="x-circle-fill" class="icon-button-colors"></sl-icon-button>
<style>
.icon-button-colors::part(base) {
color: tomato;
}
.icon-button-colors::part(base):hover {
color: #e64a2e;
}
</style>
```
### Icon Button with Tooltip
Wrap a tooltip around an icon button to provide contextual information to the user.
```html preview
<sl-tooltip content="Settings">
<sl-icon-button name="gear"></sl-icon-button>
</sl-tooltip>
```
### Disabled
```html preview
<sl-icon-button name="gear" disabled></sl-icon-button>
```
[component-metadata:sl-icon-button]

45
src/components.d.ts vendored
Wyświetl plik

@ -319,6 +319,24 @@ export namespace Components {
*/
"src": string;
}
interface SlIconButton {
/**
* Set to true to disable the button.
*/
"disabled": boolean;
/**
* An alternative description to use for accessibility. If omitted, the name or src will be used to generate it.
*/
"label": string;
/**
* The name of the icon to draw. See the icon component for a full list of icons.
*/
"name": string;
/**
* An external URL of an SVG file.
*/
"src": string;
}
interface SlInput {
/**
* The input's autocaptialize attribute.
@ -956,6 +974,12 @@ declare global {
prototype: HTMLSlIconElement;
new (): HTMLSlIconElement;
};
interface HTMLSlIconButtonElement extends Components.SlIconButton, HTMLStencilElement {
}
var HTMLSlIconButtonElement: {
prototype: HTMLSlIconButtonElement;
new (): HTMLSlIconButtonElement;
};
interface HTMLSlInputElement extends Components.SlInput, HTMLStencilElement {
}
var HTMLSlInputElement: {
@ -1084,6 +1108,7 @@ declare global {
"sl-dropdown": HTMLSlDropdownElement;
"sl-form": HTMLSlFormElement;
"sl-icon": HTMLSlIconElement;
"sl-icon-button": HTMLSlIconButtonElement;
"sl-input": HTMLSlInputElement;
"sl-menu": HTMLSlMenuElement;
"sl-menu-divider": HTMLSlMenuDividerElement;
@ -1491,6 +1516,24 @@ declare namespace LocalJSX {
*/
"src"?: string;
}
interface SlIconButton {
/**
* Set to true to disable the button.
*/
"disabled"?: boolean;
/**
* An alternative description to use for accessibility. If omitted, the name or src will be used to generate it.
*/
"label"?: string;
/**
* The name of the icon to draw. See the icon component for a full list of icons.
*/
"name"?: string;
/**
* An external URL of an SVG file.
*/
"src"?: string;
}
interface SlInput {
/**
* The input's autocaptialize attribute.
@ -2082,6 +2125,7 @@ declare namespace LocalJSX {
"sl-dropdown": SlDropdown;
"sl-form": SlForm;
"sl-icon": SlIcon;
"sl-icon-button": SlIconButton;
"sl-input": SlInput;
"sl-menu": SlMenu;
"sl-menu-divider": SlMenuDivider;
@ -2120,6 +2164,7 @@ declare module "@stencil/core" {
"sl-dropdown": LocalJSX.SlDropdown & JSXBase.HTMLAttributes<HTMLSlDropdownElement>;
"sl-form": LocalJSX.SlForm & JSXBase.HTMLAttributes<HTMLSlFormElement>;
"sl-icon": LocalJSX.SlIcon & JSXBase.HTMLAttributes<HTMLSlIconElement>;
"sl-icon-button": LocalJSX.SlIconButton & JSXBase.HTMLAttributes<HTMLSlIconButtonElement>;
"sl-input": LocalJSX.SlInput & JSXBase.HTMLAttributes<HTMLSlInputElement>;
"sl-menu": LocalJSX.SlMenu & JSXBase.HTMLAttributes<HTMLSlMenuElement>;
"sl-menu-divider": LocalJSX.SlMenuDivider & JSXBase.HTMLAttributes<HTMLSlMenuDividerElement>;

Wyświetl plik

@ -90,30 +90,6 @@
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--sl-border-radius-small);
font-family: inherit;
font-size: var(--sl-font-size-large);
font-weight: inherit;
color: var(--sl-color-gray-50);
padding: 0 var(--sl-spacing-large);
cursor: pointer;
transition: var(--sl-transition-fast) color;
-webkit-appearance: none;
&:hover,
&:focus,
&:active {
color: var(--sl-color-primary-50);
}
&:focus {
outline: none;
}
}
.focus-visible .alert__close:focus {
box-shadow: 0 0 0 var(--sl-focus-ring-width)
hsla(var(--sl-color-primary-hue), var(--sl-color-primary-saturation), 50%, var(--sl-focus-ring-alpha));
padding: 0 var(--sl-spacing-medium);
}

Wyświetl plik

@ -1,5 +1,4 @@
import { Component, Element, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';
import { focusVisible } from '../../utilities/focus-visible';
/**
* @since 2.0
@ -7,7 +6,6 @@ import { focusVisible } from '../../utilities/focus-visible';
*
* @slot - The alert's content.
* @slot icon - An icon to show in the alert.
* @slot close-icon - An icon to use in lieu of the default close icon.
*
* @part base - The component's base wrapper.
* @part icon - The container that wraps the alert icon.
@ -57,18 +55,12 @@ export class Tab {
}
componentDidLoad() {
focusVisible.observe(this.alert);
// Show on init if open
if (this.open) {
this.show();
}
}
componentDidUnload() {
focusVisible.unobserve(this.alert);
}
/** Shows the alert. */
@Method()
async show() {
@ -140,11 +132,7 @@ export class Tab {
</span>
{this.closable && (
<button part="close-button" class="alert__close" type="button" onClick={this.handleCloseClick}>
<slot name="close-icon">
<sl-icon name="x" />
</slot>
</button>
<sl-icon-button part="close-button" class="alert__close" name="x" onClick={this.handleCloseClick} />
)}
</div>
</Host>

Wyświetl plik

@ -72,31 +72,8 @@
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--sl-border-radius-small);
font-family: inherit;
font-size: var(--sl-font-size-x-large);
font-weight: inherit;
color: var(--sl-color-gray-50);
padding: 0 var(--sl-spacing-large);
cursor: pointer;
transition: var(--sl-transition-fast) color;
-webkit-appearance: none;
&:hover,
&:focus,
&:active {
color: var(--sl-color-primary-50);
}
&:focus {
outline: none;
}
}
.focus-visible .dialog__close:focus {
box-shadow: var(--sl-focus-ring-box-shadow);
}
.dialog__body {

Wyświetl plik

@ -1,6 +1,5 @@
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
import { lockBodyScrolling, unlockBodyScrolling } from '../../utilities/scroll';
import { focusVisible } from '../../utilities/focus-visible';
import { hasSlot } from '../../utilities/slot';
let id = 0;
@ -85,8 +84,6 @@ export class Dialog {
}
componentDidLoad() {
focusVisible.observe(this.dialog);
// Show on init if open
if (this.open) {
this.show();
@ -94,7 +91,6 @@ export class Dialog {
}
componentDidUnload() {
focusVisible.unobserve(this.dialog);
unlockBodyScrolling(this.host);
this.host.shadowRoot.removeEventListener('slotchange', this.updateSlots);
@ -209,9 +205,7 @@ export class Dialog {
{/* If there's no label, use an invisible character to prevent the heading from collapsing */}
{this.label || String.fromCharCode(65279)}
</span>
<button part="close-button" class="dialog__close" type="button" onClick={this.handleCloseClick}>
<sl-icon name="x"></sl-icon>
</button>
<sl-icon-button part="close-button" class="dialog__close" name="x" onClick={this.handleCloseClick} />
</header>
)}

Wyświetl plik

@ -110,31 +110,8 @@
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--sl-border-radius-small);
font-family: inherit;
font-size: var(--sl-font-size-x-large);
font-weight: inherit;
color: var(--sl-color-gray-50);
padding: 0 var(--sl-spacing-large);
cursor: pointer;
transition: var(--sl-transition-fast) color;
-webkit-appearance: none;
&:hover,
&:focus,
&:active {
color: var(--sl-color-primary-50);
}
&:focus {
outline: none;
}
}
.focus-visible .drawer__close:focus {
box-shadow: var(--sl-focus-ring-box-shadow);
}
.drawer__body {

Wyświetl plik

@ -1,6 +1,5 @@
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
import { lockBodyScrolling, unlockBodyScrolling } from '../../utilities/scroll';
import { focusVisible } from '../../utilities/focus-visible';
import { hasSlot } from '../../utilities/slot';
let id = 0;
@ -93,8 +92,6 @@ export class Drawer {
}
componentDidLoad() {
focusVisible.observe(this.drawer);
// Show on init if open
if (this.open) {
this.show();
@ -102,7 +99,6 @@ export class Drawer {
}
componentDidUnload() {
focusVisible.unobserve(this.drawer);
unlockBodyScrolling(this.host);
this.host.shadowRoot.removeEventListener('slotchange', this.updateSlots);
@ -229,9 +225,7 @@ export class Drawer {
{/* If there's no label, use an invisible character to prevent the heading from collapsing */}
{this.label || String.fromCharCode(65279)}
</span>
<button part="close-button" class="drawer__close" type="button" onClick={this.handleCloseClick}>
<sl-icon name="x"></sl-icon>
</button>
<sl-icon-button part="close-button" class="drawer__close" name="x" onClick={this.handleCloseClick} />
</header>
)}

Wyświetl plik

@ -0,0 +1,42 @@
@import 'component';
:host {
display: inline-block;
}
.icon-button {
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--sl-border-radius-medium);
font-size: inherit;
color: var(--sl-color-gray-50);
padding: var(--sl-spacing-x-small);
cursor: pointer;
transition: var(--sl-transition-medium) color;
-webkit-appearance: none;
&:hover:not(.icon-button--disabled),
&:focus:not(.icon-button--disabled) {
color: var(--sl-color-primary-50);
}
&:active:not(.icon-button--disabled) {
color: var(--sl-color-primary-40);
}
&:focus {
outline: none;
}
}
.icon-button--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.focus-visible.icon-button:focus {
box-shadow: var(--sl-focus-ring-box-shadow);
}

Wyświetl plik

@ -0,0 +1,54 @@
import { Component, Prop, h } from '@stencil/core';
import { focusVisible } from '../../utilities/focus-visible';
/**
* @since 2.0
* @status stable
*
* @part base - The component's base wrapper.
*/
@Component({
tag: 'sl-icon-button',
styleUrl: 'icon-button.scss',
shadow: true
})
export class IconButton {
button: HTMLButtonElement;
/** The name of the icon to draw. See the icon component for a full list of icons. */
@Prop() name: string;
/** An external URL of an SVG file. */
@Prop() src: string;
/** An alternative description to use for accessibility. If omitted, the name or src will be used to generate it. */
@Prop() label: string;
/** Set to true to disable the button. */
@Prop() disabled = false;
componentDidLoad() {
focusVisible.observe(this.button);
}
componentDidUnload() {
focusVisible.unobserve(this.button);
}
render() {
return (
<button
ref={el => (this.button = el)}
part="base"
class={{
'icon-button': true,
'icon-button--disabled': this.disabled
}}
type="button"
>
<sl-icon name={this.name} src={this.src} label={this.label} />
</button>
);
}
}

Wyświetl plik

@ -14,15 +14,9 @@
cursor: default;
}
.tag__clear {
display: flex;
align-items: center;
border-radius: var(--sl-border-radius-small);
cursor: pointer;
&:focus {
outline: none;
}
.tag__clear::part(base) {
color: inherit;
padding: 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Wyświetl plik

@ -73,9 +73,7 @@ export class Tag {
</span>
{this.clearable && (
<span part="clear-button" class="tag__clear" role="button" tabIndex={-1} onClick={this.handleClearClick}>
<sl-icon name="x" />
</span>
<sl-icon-button part="clear-button" name="x" class="tag__clear" onClick={this.handleClearClick} />
)}
</span>
);