mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-17 06:16:59 +08:00
chore: merge blocksuite source code (#9213)
This commit is contained in:
167
blocksuite/blocks/src/root-block/widgets/image-toolbar/index.ts
Normal file
167
blocksuite/blocks/src/root-block/widgets/image-toolbar/index.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
import { HoverController } from '@blocksuite/affine-components/hover';
|
||||
import type {
|
||||
AdvancedMenuItem,
|
||||
MenuItemGroup,
|
||||
} from '@blocksuite/affine-components/toolbar';
|
||||
import { cloneGroups } from '@blocksuite/affine-components/toolbar';
|
||||
import type { ImageBlockModel } from '@blocksuite/affine-model';
|
||||
import { WidgetComponent } from '@blocksuite/block-std';
|
||||
import { limitShift, shift } from '@floating-ui/dom';
|
||||
import { html } from 'lit';
|
||||
|
||||
import { PAGE_HEADER_HEIGHT } from '../../../_common/consts.js';
|
||||
import type { ImageBlockComponent } from '../../../image-block/image-block.js';
|
||||
import { getMoreMenuConfig } from '../../configs/toolbar.js';
|
||||
import { MORE_GROUPS, PRIMARY_GROUPS } from './config.js';
|
||||
import { ImageToolbarContext } from './context.js';
|
||||
|
||||
export const AFFINE_IMAGE_TOOLBAR_WIDGET = 'affine-image-toolbar-widget';
|
||||
|
||||
export class AffineImageToolbarWidget extends WidgetComponent<
|
||||
ImageBlockModel,
|
||||
ImageBlockComponent
|
||||
> {
|
||||
private _hoverController: HoverController | null = null;
|
||||
|
||||
private _isActivated = false;
|
||||
|
||||
private _setHoverController = () => {
|
||||
this._hoverController = null;
|
||||
this._hoverController = new HoverController(
|
||||
this,
|
||||
({ abortController }) => {
|
||||
const imageBlock = this.block;
|
||||
const selection = this.host.selection;
|
||||
|
||||
const textSelection = selection.find('text');
|
||||
if (
|
||||
!!textSelection &&
|
||||
(!!textSelection.to || !!textSelection.from.length)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const blockSelections = selection.filter('block');
|
||||
if (
|
||||
blockSelections.length > 1 ||
|
||||
(blockSelections.length === 1 &&
|
||||
blockSelections[0].blockId !== imageBlock.blockId)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const imageContainer =
|
||||
imageBlock.resizableImg ?? imageBlock.fallbackCard;
|
||||
if (!imageContainer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const context = new ImageToolbarContext(imageBlock, abortController);
|
||||
|
||||
return {
|
||||
template: html`<affine-image-toolbar
|
||||
.context=${context}
|
||||
.primaryGroups=${this.primaryGroups}
|
||||
.moreGroups=${this.moreGroups}
|
||||
.onActiveStatusChange=${(active: boolean) => {
|
||||
this._isActivated = active;
|
||||
if (!active && !this._hoverController?.isHovering) {
|
||||
this._hoverController?.abort();
|
||||
}
|
||||
}}
|
||||
></affine-image-toolbar>`,
|
||||
container: this.block,
|
||||
// stacking-context(editor-host)
|
||||
portalStyles: {
|
||||
zIndex: 'var(--affine-z-index-popover)',
|
||||
},
|
||||
computePosition: {
|
||||
referenceElement: imageContainer,
|
||||
placement: 'right-start',
|
||||
middleware: [
|
||||
shift({
|
||||
crossAxis: true,
|
||||
padding: {
|
||||
top: PAGE_HEADER_HEIGHT + 12,
|
||||
bottom: 12,
|
||||
right: 12,
|
||||
},
|
||||
limiter: limitShift(),
|
||||
}),
|
||||
],
|
||||
autoUpdate: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
{ allowMultiple: true }
|
||||
);
|
||||
|
||||
const imageBlock = this.block;
|
||||
this._hoverController.setReference(imageBlock);
|
||||
this._hoverController.onAbort = () => {
|
||||
// If the more menu is opened, don't close it.
|
||||
if (this._isActivated) return;
|
||||
this._hoverController?.abort();
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
addMoreItems = (
|
||||
items: AdvancedMenuItem<ImageToolbarContext>[],
|
||||
index?: number,
|
||||
type?: string
|
||||
) => {
|
||||
let group;
|
||||
if (type) {
|
||||
group = this.moreGroups.find(g => g.type === type);
|
||||
}
|
||||
if (!group) {
|
||||
group = this.moreGroups[0];
|
||||
}
|
||||
|
||||
if (index === undefined) {
|
||||
group.items.push(...items);
|
||||
return this;
|
||||
}
|
||||
|
||||
group.items.splice(index, 0, ...items);
|
||||
return this;
|
||||
};
|
||||
|
||||
addPrimaryItems = (
|
||||
items: AdvancedMenuItem<ImageToolbarContext>[],
|
||||
index?: number
|
||||
) => {
|
||||
if (index === undefined) {
|
||||
this.primaryGroups[0].items.push(...items);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.primaryGroups[0].items.splice(index, 0, ...items);
|
||||
return this;
|
||||
};
|
||||
|
||||
/*
|
||||
* Caches the more menu items.
|
||||
* Currently only supports configuring more menu.
|
||||
*/
|
||||
moreGroups: MenuItemGroup<ImageToolbarContext>[] = cloneGroups(MORE_GROUPS);
|
||||
|
||||
primaryGroups: MenuItemGroup<ImageToolbarContext>[] =
|
||||
cloneGroups(PRIMARY_GROUPS);
|
||||
|
||||
override firstUpdated() {
|
||||
if (this.doc.getParent(this.model.id)?.flavour === 'affine:surface') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.moreGroups = getMoreMenuConfig(this.std).configure(this.moreGroups);
|
||||
this._setHoverController();
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[AFFINE_IMAGE_TOOLBAR_WIDGET]: AffineImageToolbarWidget;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user