feat(iconbutton)!: combine button, link, and toggle variants into single components

PiperOrigin-RevId: 521789432
This commit is contained in:
Daniel Freedman 2023-04-04 09:47:37 -07:00 committed by Copybara-Service
parent 2ca34df894
commit 0aa39e8153
15 changed files with 122 additions and 578 deletions

View File

@ -1,46 +0,0 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {styles} from './lib/filled-styles.css.js';
import {IconButtonToggle} from './lib/icon-button-toggle.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-filled-icon-button-toggle': MdFilledIconButtonToggle;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This variant can toggle between icons.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-filled-icon-button-toggle')
export class MdFilledIconButtonToggle extends IconButtonToggle {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--filled': true,
'md3-icon-button--toggle-filled': true,
};
}
}

View File

@ -40,6 +40,7 @@ export class MdFilledIconButton extends IconButton {
return {
...super.getRenderClasses(),
'md3-icon-button--filled': true,
'md3-icon-button--toggle-filled': this.toggle,
};
}
}

View File

@ -1,45 +0,0 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {styles} from './lib/filled-styles.css.js';
import {LinkIconButton} from './lib/link-icon-button.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-filled-link-icon-button': MdFilledLinkIconButton;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This is a linkable variant.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-filled-link-icon-button')
export class MdFilledLinkIconButton extends LinkIconButton {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--filled': true,
};
}
}

View File

@ -1,46 +0,0 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {styles} from './lib/filled-tonal-styles.css.js';
import {IconButtonToggle} from './lib/icon-button-toggle.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-filled-tonal-icon-button-toggle': MdFilledTonalIconButtonToggle;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This variant can toggle between icons.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-filled-tonal-icon-button-toggle')
export class MdFilledTonalIconButtonToggle extends IconButtonToggle {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--filled-tonal': true,
'md3-icon-button--toggle-filled-tonal': true,
};
}
}

View File

@ -40,6 +40,7 @@ export class MdFilledTonalIconButton extends IconButton {
return {
...super.getRenderClasses(),
'md3-icon-button--filled-tonal': true,
'md3-icon-button--toggle-filled-tonal': this.toggle,
};
}
}

View File

@ -1,45 +0,0 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {styles} from './lib/filled-tonal-styles.css.js';
import {LinkIconButton} from './lib/link-icon-button.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-filled-tonal-link-icon-button': MdFilledTonalLinkIconButton;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This is a linkable variant.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-filled-tonal-link-icon-button')
export class MdFilledTonalLinkIconButton extends LinkIconButton {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--filled-tonal': true,
};
}
}

View File

@ -7,12 +7,11 @@
import {Harness} from '../testing/harness.js';
import {IconButton} from './lib/icon-button.js';
import {IconButtonToggle} from './lib/icon-button-toggle.js';
/**
* Test harness for icon buttons.
*/
export class IconButtonHarness extends Harness<IconButton|IconButtonToggle> {
export class IconButtonHarness extends Harness<IconButton> {
protected override async getInteractiveElement() {
await this.element.updateComplete;
return this.element.renderRoot.querySelector('.md3-icon-button') as

View File

@ -4,8 +4,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
import './standard-icon-button-toggle.js';
import './standard-link-icon-button.js';
import './standard-icon-button.js';
import {html} from 'lit';
@ -13,7 +11,6 @@ import {html} from 'lit';
import {Environment} from '../testing/environment.js';
import {IconButtonHarness} from './harness.js';
import {MdStandardIconButtonToggle} from './standard-icon-button-toggle.js';
const ICON_BUTTON_TEMPLATE = html`
<md-standard-icon-button aria-label="Star">
@ -21,15 +18,15 @@ const ICON_BUTTON_TEMPLATE = html`
</md-standard-icon-button>
`;
const LINK_ICON_BUTTON_TEMPLATE = html`
<md-standard-link-icon-button aria-label="Star">
<md-standard-icon-button aria-label="Star" href="https://google.com">
star
</md-standard-link-icon-button>
</md-standard-icon-button>
`;
const ICON_BUTTON_TOGGLE_TEMPLATE = html`
<md-standard-icon-button-toggle aria-label="Star">
<md-standard-icon-button toggle aria-label="Star">
<md-icon slot="onIcon">star</md-icon>
<md-icon slot="offIcon">star_border</md-icon>
</md-standard-icon-button-toggle>
</md-standard-icon-button>
`;
interface IconButtonInternals {
@ -43,7 +40,7 @@ describe('icon button tests', () => {
it('setting `disabled` updates the disabled attribute on the native ' +
'button element',
async () => {
const {element} = await setUpTest('md-standard-icon-button');
const {element} = await setUpTest('button');
const button = element.shadowRoot!.querySelector('button')!;
element.disabled = true;
@ -58,7 +55,7 @@ describe('icon button tests', () => {
it('setting `ariaLabel` updates the aria-label attribute on the native ' +
'button element',
async () => {
const {element} = await setUpTest('md-standard-icon-button');
const {element} = await setUpTest('button');
const button = element.shadowRoot!.querySelector('button')!;
element.ariaLabel = 'test';
@ -67,12 +64,13 @@ describe('icon button tests', () => {
});
});
describe('md-standard-link-icon-button', () => {
describe('md-standard-icon-button link', () => {
it('setting `ariaLabel` updates the aria-label attribute on the anchor' +
'tag',
async () => {
const {element} = await setUpTest('md-standard-link-icon-button');
const {element} = await setUpTest('link');
const anchor = element.shadowRoot!.querySelector('a')!;
expect(anchor).not.toBeNull();
element.ariaLabel = 'test';
await element.updateComplete;
@ -80,11 +78,11 @@ describe('icon button tests', () => {
});
});
describe('md-standard-icon-button-toggle', () => {
describe('md-standard-icon-button toggle', () => {
it('setting `disabled` updates the disabled attribute on the native ' +
'button element',
async () => {
const {element} = await setUpTest('md-standard-icon-button-toggle');
const {element} = await setUpTest('toggle');
const button = element.shadowRoot!.querySelector('button')!;
element.disabled = true;
@ -99,7 +97,7 @@ describe('icon button tests', () => {
it('setting `ariaLabel` updates the aria-label attribute on the native ' +
'button element',
async () => {
const {element} = await setUpTest('md-standard-icon-button-toggle');
const {element} = await setUpTest('toggle');
const button = element.shadowRoot!.querySelector('button')!;
element.ariaLabel = 'test';
@ -108,12 +106,7 @@ describe('icon button tests', () => {
});
it('toggles the `selected` state when button is clicked', async () => {
const {element, harness} =
await setUpTest('md-standard-icon-button-toggle');
if (!(element instanceof MdStandardIconButtonToggle)) {
throw new Error(
'Icon button is not instance of MdStandardIconButtonToggle.');
}
const {element, harness} = await setUpTest('toggle');
expect(element.selected).toBeFalse();
await harness.clickWithMouse();
@ -123,12 +116,7 @@ describe('icon button tests', () => {
});
it('fires input and change events when clicked', async () => {
const {element, harness} =
await setUpTest('md-standard-icon-button-toggle');
if (!(element instanceof MdStandardIconButtonToggle)) {
throw new Error(
'Icon button is not instance of MdStandardIconButtonToggle.');
}
const {element, harness} = await setUpTest('toggle');
let changeEvent = false;
let inputEvent = false;
element.addEventListener('input', () => inputEvent = true);
@ -142,11 +130,7 @@ describe('icon button tests', () => {
it('setting `selected` updates the aria-pressed attribute on the native button element',
async () => {
const {element} = await setUpTest('md-standard-icon-button-toggle');
if (!(element instanceof MdStandardIconButtonToggle)) {
throw new Error(
'Icon button is not instance of MdStandardIconButtonToggle.');
}
const {element} = await setUpTest('toggle');
element.selected = true;
await element.updateComplete;
@ -159,11 +143,7 @@ describe('icon button tests', () => {
});
it('button with toggled aria label toggles aria label', async () => {
const {element} = await setUpTest('md-standard-icon-button-toggle');
if (!(element instanceof MdStandardIconButtonToggle)) {
throw new Error(
'Icon button is not instance of MdStandardIconButtonToggle.');
}
const {element} = await setUpTest('toggle');
element.ariaLabelSelected = 'aria label on';
element.ariaLabel = 'aria label off';
await element.updateComplete;
@ -213,23 +193,24 @@ describe('icon button tests', () => {
});
});
async function setUpTest(tagName: string) {
async function setUpTest(type: string) {
let template;
switch (tagName) {
case 'md-standard-icon-button':
switch (type) {
case 'button':
template = ICON_BUTTON_TEMPLATE;
break;
case 'md-standard-link-icon-button':
case 'link':
template = LINK_ICON_BUTTON_TEMPLATE;
break;
case 'md-standard-icon-button-toggle':
case 'toggle':
template = ICON_BUTTON_TOGGLE_TEMPLATE;
break;
default:
throw new Error('Invalid tag name: ' + tagName);
throw new Error('Invalid tag name: ' + type);
}
const element = env.render(template).querySelector(tagName)!;
const element =
env.render(template).querySelector('md-standard-icon-button')!;
await env.waitForStability();
return {
element,

View File

@ -1,91 +0,0 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
// Required for @ariaProperty
// tslint:disable:no-new-decorators
import '../../focus/focus-ring.js';
import '../../icon/icon.js';
import '../../ripple/ripple.js';
import {html, nothing, TemplateResult} from 'lit';
import {property} from 'lit/decorators.js';
import {ClassInfo, classMap} from 'lit/directives/class-map.js';
import {when} from 'lit/directives/when.js';
import {ripple} from '../../ripple/directive.js';
import {IconButton} from './icon-button.js';
/**
* @fires change {Event}
* Dispatched whenever `selected` is changed via user click
*
* @fires input {InputEvent}
* Dispatched whenever `selected` is changed via user click
*/
export class IconButtonToggle extends IconButton {
/**
* The `aria-label` of the button when the toggle button is selected.
*/
@property({type: String}) ariaLabelSelected!: string;
/**
* Sets the selected state. When false, displays the default icon. When true,
* displays the `selectedIcon`, or the default icon If no `selectedIcon` is
* provided.
*/
@property({type: Boolean, reflect: true}) selected = false;
protected override render(): TemplateResult {
const hasToggledAriaLabel = this.ariaLabel && this.ariaLabelSelected;
const ariaPressedValue = hasToggledAriaLabel ? nothing : this.selected;
const ariaLabelValue = (hasToggledAriaLabel && this.selected) ?
this.ariaLabelSelected :
this.ariaLabel;
return html`<button
class="md3-icon-button ${classMap(this.getRenderClasses())}"
aria-pressed="${ariaPressedValue}"
aria-label="${ariaLabelValue || nothing}"
?disabled="${this.disabled}"
@focus="${this.handleFocus}"
@blur="${this.handleBlur}"
@pointerdown="${this.handlePointerDown}"
@click="${this.handleClick}"
${ripple(this.getRipple)}>
${this.renderFocusRing()}
${when(this.showRipple, this.renderRipple)}
${this.renderTouchTarget()}
${!this.selected ? this.renderIcon() : nothing}
${this.selected ? this.renderSelectedIcon() : nothing}
</button>`;
}
protected renderSelectedIcon() {
// Use default slot as fallback to not require specifying multiple icons
return html`<md-icon class="md3-icon-button__icon md3-icon-button__icon--selected"><slot name="selectedIcon"><slot></slot></slot></md-icon>`;
}
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--selected': this.selected,
};
}
protected handleClick() {
if (this.disabled) {
return;
}
this.selected = !this.selected;
this.dispatchEvent(
new InputEvent('input', {bubbles: true, composed: true}));
// Bubbles but does not compose to mimic native browser <input> & <select>
// Additionally, native change event is not an InputEvent.
this.dispatchEvent(new Event('change', {bubbles: true}));
}
}

View File

@ -11,11 +11,11 @@ import '../../focus/focus-ring.js';
import '../../icon/icon.js';
import '../../ripple/ripple.js';
import {html, LitElement, TemplateResult} from 'lit';
import {html, LitElement, nothing, TemplateResult} from 'lit';
import {property, query, queryAsync, state} from 'lit/decorators.js';
import {ClassInfo, classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {when} from 'lit/directives/when.js';
import {html as staticHtml, literal} from 'lit/static-html.js';
import {isRtl} from '../../controller/is-rtl.js';
import {ariaProperty} from '../../decorators/aria-property.js';
@ -24,6 +24,8 @@ import {ripple} from '../../ripple/directive.js';
import {MdRipple} from '../../ripple/ripple.js';
import {ARIAExpanded, ARIAHasPopup} from '../../types/aria.js';
type LinkTarget = '_blank'|'_parent'|'_self'|'_top';
// tslint:disable-next-line:enforce-comments-on-exported-symbols
export class IconButton extends LitElement {
/**
@ -36,20 +38,46 @@ export class IconButton extends LitElement {
*/
@property({type: Boolean}) flipIconInRtl = false;
@state() protected flipIcon: boolean = isRtl(this, this.flipIconInRtl);
@ariaProperty
@property({type: String, attribute: 'data-aria-label'})
@property({attribute: 'data-aria-label'})
override ariaLabel!: string;
@ariaProperty
@property({type: String, attribute: 'data-aria-haspopup'})
@property({attribute: 'data-aria-haspopup'})
override ariaHasPopup!: ARIAHasPopup;
@ariaProperty
@property({type: String, attribute: 'data-aria-expanded'})
@property({attribute: 'data-aria-expanded'})
override ariaExpanded!: ARIAExpanded;
/**
* Sets the underlying `HTMLAnchorElement`'s `href` resource attribute.
*/
@property() href = '';
/**
* Sets the underlying `HTMLAnchorElement`'s `target` attribute.
*/
@property() target = '';
/**
* The `aria-label` of the button when the button is toggleable and selected.
*/
@property() ariaLabelSelected!: string;
/**
* When true, the button will toggle between selected and unselected
* states
*/
@property({type: Boolean}) toggle = false;
/**
* Sets the selected state. When false, displays the default icon. When true,
* displays the `selectedIcon`, or the default icon If no `selectedIcon` is
* provided.
*/
@property({type: Boolean, reflect: true}) selected = false;
@query('button') protected buttonElement!: HTMLElement;
@queryAsync('md-ripple') protected ripple!: Promise<MdRipple|null>;
@ -58,36 +86,70 @@ export class IconButton extends LitElement {
@state() protected showRipple = false;
@state() protected flipIcon: boolean = isRtl(this, this.flipIconInRtl);
protected getRipple = () => {
this.showRipple = true;
return this.ripple;
};
protected readonly renderRipple = () => {
return html`<md-ripple ?disabled="${this.disabled}"></md-ripple>`;
return html`<md-ripple ?disabled="${
!this.href && this.disabled}"></md-ripple>`;
};
/**
* Link buttons cannot be disabled.
*/
override willUpdate() {
if (this.href) {
this.disabled = false;
}
}
protected override render(): TemplateResult {
return html`<button
const tag = this.href ? literal`div` : literal`button`;
const hasToggledAriaLabel = this.ariaLabel && this.ariaLabelSelected;
const ariaPressedValue = hasToggledAriaLabel ? nothing : this.selected;
let ariaLabelValue: string|typeof nothing = nothing;
if (!this.href) {
ariaLabelValue = (hasToggledAriaLabel && this.selected) ?
this.ariaLabelSelected :
this.ariaLabel;
}
return staticHtml`<${tag}
class="md3-icon-button ${classMap(this.getRenderClasses())}"
aria-label="${ifDefined(this.ariaLabel)}"
aria-haspopup="${ifDefined(this.ariaHasPopup)}"
aria-expanded="${ifDefined(this.ariaExpanded)}"
?disabled="${this.disabled}"
aria-label="${ariaLabelValue || nothing}"
aria-haspopup="${!this.href && this.ariaHasPopup || nothing}"
aria-expanded="${!this.href && this.ariaExpanded || nothing}"
aria-pressed="${ariaPressedValue}"
?disabled="${!this.href && this.disabled}"
@focus="${this.handleFocus}"
@blur="${this.handleBlur}"
@pointerdown="${this.handlePointerDown}"
@click="${this.handleClick}"
${ripple(this.getRipple)}>
${this.renderFocusRing()}
${when(this.showRipple, this.renderRipple)}
${this.renderIcon()}
${!this.selected ? this.renderIcon() : nothing}
${this.selected ? this.renderSelectedIcon() : nothing}
${this.renderTouchTarget()}
</button>`;
${this.href && this.renderLink()}
</${tag}>`;
}
protected renderLink() {
return html`<a class="md3-icon-button__link" href="${this.href}"
target="${this.target as LinkTarget || nothing}"
@focus="${this.handleFocus}"
@blur="${this.handleBlur}"
aria-label="${this.ariaLabel || nothing}"></a>`;
}
protected getRenderClasses(): ClassInfo {
return {
'md3-icon-button--flip-icon': this.flipIcon,
'md3-icon-button--selected': this.toggle && this.selected,
};
}
@ -95,6 +157,11 @@ export class IconButton extends LitElement {
return html`<md-icon class="md3-icon-button__icon"><slot></slot></md-icon>`;
}
protected renderSelectedIcon() {
// Use default slot as fallback to not require specifying multiple icons
return html`<md-icon class="md3-icon-button__icon md3-icon-button__icon--selected"><slot name="selectedIcon"><slot></slot></slot></md-icon>`;
}
protected renderTouchTarget(): TemplateResult {
return html`<span class="md3-icon-button__touch"></span>`;
}
@ -121,4 +188,17 @@ export class IconButton extends LitElement {
protected handleBlur() {
this.showFocusRing = false;
}
protected handleClick() {
if (!this.toggle || this.disabled) {
return;
}
this.selected = !this.selected;
this.dispatchEvent(
new InputEvent('input', {bubbles: true, composed: true}));
// Bubbles but does not compose to mimic native browser <input> & <select>
// Additionally, native change event is not an InputEvent.
this.dispatchEvent(new Event('change', {bubbles: true}));
}
}

View File

@ -1,65 +0,0 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {html, TemplateResult} from 'lit';
import {property} from 'lit/decorators.js';
import {classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {when} from 'lit/directives/when.js';
import {ripple} from '../../ripple/directive.js';
import {IconButton} from './icon-button.js';
/**
* Note that we cast `linkTarget` to this type, below. The Lit compiler
* enforces the `target` attribute value to be of this type, but this is not
* compatible with the generated Wit Soy/JS, which expects `linkTarget`
* to be a string type.
*/
type LinkTarget = '_blank'|'_parent'|'_self'|'_top';
// tslint:disable-next-line:enforce-comments-on-exported-symbols
export class LinkIconButton extends IconButton {
/**
* Sets the underlying `HTMLAnchorElement`'s `href` resource attribute.
*/
@property({type: String}) linkHref = '';
/**
* Sets the underlying `HTMLAnchorElement`'s `target` attribute.
*/
@property({type: String}) linkTarget!: string;
/**
* Link buttons cannot be disabled.
*/
override disabled = false;
override willUpdate() {
this.disabled = false;
}
protected override render(): TemplateResult {
return html`<div
class="md3-icon-button ${classMap(this.getRenderClasses())}"
@focus="${this.handleFocus}"
@blur="${this.handleBlur}"
@pointerdown="${this.handlePointerDown}"
${ripple(this.getRipple)}>
${this.renderFocusRing()}
${when(this.showRipple, this.renderRipple)}
${this.renderIcon()}
${this.renderTouchTarget()}
<a class="md3-icon-button__link" href="${this.linkHref}"
target="${ifDefined(this.linkTarget as LinkTarget)}"
aria-label="${ifDefined(this.ariaLabel)}"
@focus="${this.handleFocus}"
@blur="${this.handleBlur}">
</a>
</div>`;
}
}

View File

@ -1,45 +0,0 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {IconButtonToggle} from './lib/icon-button-toggle.js';
import {styles} from './lib/outlined-styles.css.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-outlined-icon-button-toggle': MdOutlinedIconButtonToggle;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This variant can toggle between icons.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-outlined-icon-button-toggle')
export class MdOutlinedIconButtonToggle extends IconButtonToggle {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--outlined': true,
};
}
}

View File

@ -1,45 +0,0 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {LinkIconButton} from './lib/link-icon-button.js';
import {styles} from './lib/outlined-styles.css.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-outlined-link-icon-button': MdOutlinedLinkIconButton;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This is a linkable variant.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-outlined-link-icon-button')
export class MdOutlinedLinkIconButton extends LinkIconButton {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--outlined': true,
};
}
}

View File

@ -1,45 +0,0 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {IconButtonToggle} from './lib/icon-button-toggle.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
import {styles} from './lib/standard-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-standard-icon-button-toggle': MdStandardIconButtonToggle;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This variant can toggle between icons.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-standard-icon-button-toggle')
export class MdStandardIconButtonToggle extends IconButtonToggle {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--standard': true,
};
}
}

View File

@ -1,45 +0,0 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {customElement} from 'lit/decorators.js';
import {ClassInfo} from 'lit/directives/class-map.js';
import {LinkIconButton} from './lib/link-icon-button.js';
import {styles as sharedStyles} from './lib/shared-styles.css.js';
import {styles} from './lib/standard-styles.css.js';
declare global {
interface HTMLElementTagNameMap {
'md-standard-link-icon-button': MdStandardLinkIconButton;
}
}
/**
* @summary Icon buttons help people take supplementary actions with a single
* tap. This is a linkable variant.
*
* @description
* __Emphasis:__ Low emphasis For optional or supplementary actions with the
* least amount of prominence.
*
* __Rationale:__ The most compact and unobtrusive type of button, icon buttons
* are used for optional supplementary actions such as "Bookmark" or "Star."
*
* __Example usages:__
* - Add to Favorites
* - Print
*/
@customElement('md-standard-link-icon-button')
export class MdStandardLinkIconButton extends LinkIconButton {
static override styles = [sharedStyles, styles];
protected override getRenderClasses(): ClassInfo {
return {
...super.getRenderClasses(),
'md3-icon-button--standard': true,
};
}
}