import type { BlockStdScope } from '@blockeditor/block-std'; import { WithDisposable } from '@blockeditor/lit'; import { Slice } from '@blockeditor/store'; import { css, html, LitElement } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import type { EmbedFigmaBlockComponent } from '../../../embed-figma-block/embed-figma-block.js'; import type { EmbedFigmaModel } from '../../../embed-figma-block/embed-figma-model.js'; import type { EmbedGithubBlockComponent } from '../../../embed-github-block/embed-github-block.js'; import type { EmbedGithubModel } from '../../../embed-github-block/embed-github-model.js'; import type { EmbedLinkedDocBlockComponent } from '../../../embed-linked-doc-block/embed-linked-doc-block.js'; import type { EmbedLinkedDocModel } from '../../../embed-linked-doc-block/embed-linked-doc-model.js'; import type { EmbedYoutubeBlockComponent } from '../../../embed-youtube-block/embed-youtube-block.js'; import type { EmbedYoutubeModel } from '../../../embed-youtube-block/embed-youtube-model.js'; import type { BookmarkBlockComponent, BookmarkBlockModel, } from '../../../index.js'; import { CopyIcon, DeleteIcon, DuplicateIcon, OpenIcon, RefreshIcon, } from '../../icons/text.js'; import { toast } from '../toast.js'; @customElement('embed-card-more-menu') export class EmbedCardMoreMenu extends WithDisposable(LitElement) { static override styles = css` .embed-card-more-menu { border-radius: 8px; padding: 8px; background: var(--affine-background-overlay-panel-color); box-shadow: var(--affine-shadow-2); } .embed-card-more-menu .menu-item { display: flex; justify-content: flex-start; align-items: center; width: 100%; } .embed-card-more-menu .menu-item:hover { background: var(--affine-hover-color); } .embed-card-more-menu .menu-item:hover.delete { background: var(--affine-background-error-color); color: var(--affine-error-color); } .embed-card-more-menu .menu-item:hover.delete > svg { color: var(--affine-error-color); } .embed-card-more-menu .menu-item svg { margin: 0 8px; } .embed-card-more-menu .divider { width: 148px; height: 1px; margin: 8px; background-color: var(--affine-border-color); } `; @property({ attribute: false }) model!: | BookmarkBlockModel | EmbedGithubModel | EmbedYoutubeModel | EmbedFigmaModel | EmbedLinkedDocModel; @property({ attribute: false }) block!: | BookmarkBlockComponent | EmbedGithubBlockComponent | EmbedYoutubeBlockComponent | EmbedFigmaBlockComponent | EmbedLinkedDocBlockComponent; @property({ attribute: false }) std!: BlockStdScope; @property({ attribute: false }) abortController!: AbortController; private _open() { this.block.open(); this.abortController.abort(); } private async _copyBlock() { const slice = Slice.fromModels(this.model.page, [this.model]); await this.std.clipboard.copySlice(slice); toast(this.block.host, 'Copied link to clipboard'); this.abortController.abort(); } private _duplicateBlock() { const model = this.model; const keys = model.keys as (keyof typeof model)[]; const values = keys.map(key => model[key]); const blockProps = Object.fromEntries( keys.map((key, i) => [key, values[i]]) ); const { width, height, xywh, rotate, zIndex, ...duplicateProps } = blockProps; const { page } = model; const parent = page.getParent(model); const index = parent?.children.indexOf(model); page.addBlock(model.flavour, duplicateProps, parent, index); this.abortController.abort(); } private _refreshData() { this.block.refreshData(); this.abortController.abort(); } override render() { return html`
`; } } declare global { interface HTMLElementTagNameMap { 'embed-card-more-menu': EmbedCardMoreMenu; } }