From 216e2268d7e0a4044ad1818d881dbd487a409515 Mon Sep 17 00:00:00 2001 From: shonya3 Date: Sun, 3 Sep 2023 19:31:26 +0300 Subject: [PATCH] wc: add icon-button --- packages/wc/src/wc/file-card/file-card.ts | 72 ++++++- packages/wc/src/wc/icon-button/icon-button.ts | 203 ++++++++++++++++++ 2 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 packages/wc/src/wc/icon-button/icon-button.ts diff --git a/packages/wc/src/wc/file-card/file-card.ts b/packages/wc/src/wc/file-card/file-card.ts index ee56baf0..77346a15 100644 --- a/packages/wc/src/wc/file-card/file-card.ts +++ b/packages/wc/src/wc/file-card/file-card.ts @@ -5,6 +5,7 @@ import { DivTableElement } from '../div-table/div-table'; import { BasePopupElement } from '../base-popup'; import { FixedNamesElement } from './fixed-names/fixed-names'; import { NotCardsElement } from './not-cards/not-cards'; +import { IconButtonElement } from '../icon-button/icon-button'; import { DivinationCardsSample, League, TradeLeague, isTradeLeague } from '@divicards/shared/types'; import { property, query } from 'lit/decorators.js'; import { ACTIVE_LEAGUE } from '@divicards/shared/lib'; @@ -35,7 +36,14 @@ export interface Events { export class FileCardElement extends BaseElement { static override get defineList() { - return [LeagueSelectElement, DivTableElement, BasePopupElement, FixedNamesElement, NotCardsElement]; + return [ + LeagueSelectElement, + DivTableElement, + BasePopupElement, + FixedNamesElement, + NotCardsElement, + IconButtonElement, + ]; } static override tag = 'wc-file-card'; @@ -112,7 +120,10 @@ export class FileCardElement extends BaseElement { })} >

${this.filename}

- + + Here ${this.chunk()} `; } @@ -190,6 +201,7 @@ export class FileCardElement extends BaseElement { static override styles = [ this.baseStyles, + iconButtonStyles(), css` .league { display: flex; @@ -306,3 +318,59 @@ export class FileCardElement extends BaseElement { `, ]; } + +function iconButtonStyles() { + return css` + .icon-button { + /* Focus rings */ + --sl-focus-ring-color: rgb(105, 208, 255); + --sl-focus-ring-style: solid; + --sl-focus-ring-width: 3px; + --sl-focus-ring: var(--sl-focus-ring-style) var(--sl-focus-ring-width) var(--sl-focus-ring-color); + --sl-focus-ring-offset: 1px; + + display: inline-block; + color: rgb(142, 142, 154); + + flex: 0 0 auto; + display: flex; + align-items: center; + background: none; + border: none; + border-radius: var(--sl-border-radius-medium); + font-size: inherit; + color: inherit; + padding: var(--sl-spacing-x-small); + cursor: pointer; + transition: var(--sl-transition-x-fast) color; + -webkit-appearance: none; + } + + .icon-button:hover:not(.icon-button--disabled), + .icon-button:focus-visible:not(.icon-button--disabled) { + color: rgb(39, 186, 253); + } + + .icon-button:active:not(.icon-button--disabled) { + color: rgb(105, 208, 255); + } + + .icon-button:focus { + outline: none; + } + + .icon-button--disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .icon-button:focus-visible { + outline: var(--sl-focus-ring); + outline-offset: var(--sl-focus-ring-offset); + } + + .icon-button__icon { + pointer-events: none; + } + `; +} diff --git a/packages/wc/src/wc/icon-button/icon-button.ts b/packages/wc/src/wc/icon-button/icon-button.ts new file mode 100644 index 00000000..e935bd50 --- /dev/null +++ b/packages/wc/src/wc/icon-button/icon-button.ts @@ -0,0 +1,203 @@ +import { html, css, svg } from 'lit'; +import { property, query, state } from 'lit/decorators.js'; +import { BaseElement } from '../base-element'; +import { classMap } from 'lit/directives/class-map.js'; +declare global { + interface HTMLElementTagNameMap { + 'wc-icon-button': IconButtonElement; + } +} + +export class IconButtonElement extends BaseElement { + static override tag = 'wc-icon-button'; + static override styles = [this.baseStyles, iconButtonStyles(), base()]; + + @query('.icon-button') button!: HTMLButtonElement | HTMLLinkElement; + + @state() private hasFocus = false; + + /** The name of the icon to draw. Available names depend on the icon library being used. */ + @property() name?: string; + + /** The name of a registered custom icon library. */ + @property() library?: string; + + /** + * An external URL of an SVG file. Be sure you trust the content you are including, as it will be executed as code and + * can result in XSS attacks. + */ + @property() src?: string; + + /** When set, the underlying button will be rendered as an `` with this `href` instead of a ` + `; + } + + protected icon() { + switch (this.name) { + case 'close': { + return html` + + `; + } + + default: + throw new Error('unsupported icon name'); + } + } +} + +function iconButtonStyles() { + return css` + .icon-button { + /* Focus rings */ + --sl-focus-ring-color: rgb(105, 208, 255); + --sl-focus-ring-style: solid; + --sl-focus-ring-width: 3px; + --sl-focus-ring: var(--sl-focus-ring-style) var(--sl-focus-ring-width) var(--sl-focus-ring-color); + --sl-focus-ring-offset: 1px; + + display: inline-block; + color: rgb(142, 142, 154); + + flex: 0 0 auto; + display: flex; + align-items: center; + background: none; + border: none; + border-radius: var(--sl-border-radius-medium); + font-size: inherit; + color: inherit; + padding: var(--sl-spacing-x-small); + cursor: pointer; + transition: var(--sl-transition-x-fast) color; + -webkit-appearance: none; + } + + .icon-button:hover:not(.icon-button--disabled), + .icon-button:focus-visible:not(.icon-button--disabled) { + color: rgb(39, 186, 253); + } + + .icon-button:active:not(.icon-button--disabled) { + color: rgb(105, 208, 255); + } + + .icon-button:focus { + outline: none; + } + + .icon-button--disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .icon-button:focus-visible { + outline: var(--sl-focus-ring); + outline-offset: var(--sl-focus-ring-offset); + } + + .icon-button__icon { + pointer-events: none; + } + `; +} + +function base() { + return css` + :host { + box-sizing: border-box; + } + + :host *, + :host *::before, + :host *::after { + box-sizing: inherit; + } + + [hidden] { + display: none !important; + } + `; +}