kopia lustrzana https://github.com/shoelace-style/shoelace
Add icon button
rodzic
79b84cc47e
commit
96f32122c0
|
@ -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)
|
||||
|
|
|
@ -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]
|
|
@ -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>;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
Ładowanie…
Reference in New Issue