import { DefaultTool } from '@blocksuite/affine-block-surface'; import { darkToolbarStyles, lightToolbarStyles, } from '@blocksuite/affine-components/toolbar'; import { EditPropsStore, ThemeProvider, } from '@blocksuite/affine-shared/services'; import { requestConnectedFrame, stopPropagation, } from '@blocksuite/affine-shared/utils'; import { EdgelessDraggableElementController } from '@blocksuite/affine-widget-edgeless-toolbar'; import type { Bound } from '@blocksuite/global/gfx'; import { WithDisposable } from '@blocksuite/global/lit'; import type { BlockComponent } from '@blocksuite/std'; import { GfxControllerIdentifier } from '@blocksuite/std/gfx'; import { baseTheme } from '@toeverything/theme'; import { css, html, LitElement, nothing, unsafeCSS } from 'lit'; import { property, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { styleMap } from 'lit/directives/style-map.js'; import { unsafeSVG } from 'lit/directives/unsafe-svg.js'; import { createTemplateJob } from '../services/template.js'; import { builtInTemplates } from './builtin-templates.js'; import { defaultPreview, Triangle } from './cards.js'; import type { Template } from './template-type.js'; import { cloneDeep } from './utils.js'; export class EdgelessTemplatePanel extends WithDisposable(LitElement) { static override styles = css` :host { position: absolute; font-family: ${unsafeCSS(baseTheme.fontSansFamily)}; z-index: 1; } .edgeless-templates-panel { width: 467px; height: 568px; border-radius: 12px; background-color: var(--affine-background-overlay-panel-color); box-shadow: 0px 10px 80px 0px rgba(0, 0, 0, 0.2); display: flex; flex-direction: column; } ${unsafeCSS(lightToolbarStyles('.edgeless-templates-panel'))} ${unsafeCSS(darkToolbarStyles('.edgeless-templates-panel'))} .search-bar { padding: 21px 24px; font-size: 18px; color: var(--affine-secondary); border-bottom: 1px solid var(--affine-divider-color); flex-shrink: 0; } .search-input { border: 0; color: var(--affine-text-primary-color); font-size: 20px; background-color: inherit; outline: none; width: 100%; } .search-input::placeholder { color: var(--affine-text-secondary-color); } .template-categories { display: flex; padding: 6px 8px; gap: 4px; overflow-x: scroll; flex-shrink: 0; } .category-entry { color: var(--affine-text-primary-color); font-size: 12px; font-weight: 600; line-height: 20px; border-radius: 8px; flex-shrink: 0; flex-grow: 0; width: fit-content; padding: 4px 9px; cursor: pointer; } .category-entry.selected, .category-entry:hover { color: var(--affine-text-primary-color); background-color: var(--affine-background-tertiary-color); } .template-viewport { position: relative; flex-grow: 1; } .template-scrollcontent { overflow: hidden; height: 100%; width: 100%; } .template-list { padding: 10px; display: flex; align-items: flex-start; align-content: flex-start; gap: 10px 20px; flex-wrap: wrap; } .template-item { position: relative; width: 135px; height: 80px; box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.02); background-color: var(--affine-background-primary-color); border-radius: 4px; cursor: pointer; } .template-item > svg { display: block; margin: 0 auto; width: 135px; height: 80px; color: var(--affine-background-primary-color); } /* .template-item:hover::before { content: attr(data-hover-text); position: absolute; display: block; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 110px; border-radius: 8px; padding: 4px 22px; box-sizing: border-box; z-index: 1; text-align: center; font-size: 12px; background-color: var(--affine-primary-color); color: var(--affine-white); } */ .template-item:hover::after { content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 100%; box-sizing: border-box; border: 1px solid var(--affine-black-10); border-radius: 4px; background-color: var(--affine-hover-color); } .template-item.loading::before { display: none; } .template-item.loading > affine-template-loading { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } .template-item img.template-preview { object-fit: contain; width: 100%; height: 100%; display: block; } .arrow { bottom: 0; position: absolute; transform: translateY(20px); color: var(--affine-background-overlay-panel-color); } `; static templates = builtInTemplates; private _fetchJob: null | { cancel: () => void } = null; draggableController!: EdgelessDraggableElementController