refactor(editor): edgeless bookmark toolbar config extension (#10711)

This commit is contained in:
fundon
2025-03-19 02:24:26 +00:00
parent 70fe521300
commit d8567e669a
17 changed files with 537 additions and 101 deletions
@@ -0,0 +1 @@
export * from '@blocksuite/affine-components/size-dropdown-menu';
+2
View File
@@ -32,6 +32,7 @@ import { IconButton } from '@blocksuite/affine-components/icon-button';
import { effects as componentLinkPreviewEffects } from '@blocksuite/affine-components/link-preview';
import { effects as componentLinkedDocTitleEffects } from '@blocksuite/affine-components/linked-doc-title';
import { effects as componentPortalEffects } from '@blocksuite/affine-components/portal';
import { effects as componentSizeDropdownMenuEffects } from '@blocksuite/affine-components/size-dropdown-menu';
import { SmoothCorner } from '@blocksuite/affine-components/smooth-corner';
import { effects as componentToggleButtonEffects } from '@blocksuite/affine-components/toggle-button';
import { ToggleSwitch } from '@blocksuite/affine-components/toggle-switch';
@@ -147,6 +148,7 @@ export function effects() {
componentHighlightDropdownMenuEffects();
componentViewDropdownMenuEffects();
componentTooltipContentWithShortcutEffects();
componentSizeDropdownMenuEffects();
widgetScrollAnchoringEffects();
widgetFrameTitleEffects();
@@ -11,6 +11,7 @@
"license": "MIT",
"dependencies": {
"@blocksuite/affine-block-embed": "workspace:*",
"@blocksuite/affine-block-surface": "workspace:*",
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
@@ -1,16 +1,11 @@
import { BookmarkBlockSchema } from '@blocksuite/affine-model';
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
import {
BlockFlavourIdentifier,
BlockViewExtension,
FlavourExtension,
} from '@blocksuite/block-std';
import { BlockViewExtension, FlavourExtension } from '@blocksuite/block-std';
import type { ExtensionType } from '@blocksuite/store';
import { literal } from 'lit/static-html.js';
import { BookmarkBlockAdapterExtensions } from './adapters/extension';
import { BookmarkSlashMenuConfigExtension } from './configs/slash-menu';
import { builtinToolbarConfig } from './configs/toolbar';
import { createBuiltinToolbarConfigExtension } from './configs/toolbar';
const flavour = BookmarkBlockSchema.model.flavour;
@@ -22,9 +17,6 @@ export const BookmarkBlockSpec: ExtensionType[] = [
: literal`affine-bookmark`;
}),
BookmarkBlockAdapterExtensions,
ToolbarModuleExtension({
id: BlockFlavourIdentifier(flavour),
config: builtinToolbarConfig,
}),
createBuiltinToolbarConfigExtension(flavour),
BookmarkSlashMenuConfigExtension,
].flat();
@@ -1,16 +1,29 @@
import { EmbedIframeService } from '@blocksuite/affine-block-embed';
import { reassociateConnectorsCommand } from '@blocksuite/affine-block-surface';
import { toast } from '@blocksuite/affine-components/toast';
import { BookmarkBlockModel } from '@blocksuite/affine-model';
import {
BookmarkBlockModel,
BookmarkStyles,
type EmbedCardStyle,
} from '@blocksuite/affine-model';
import {
EMBED_CARD_HEIGHT,
EMBED_CARD_WIDTH,
} from '@blocksuite/affine-shared/consts';
import {
ActionPlacement,
EmbedOptionProvider,
FeatureFlagService,
type LinkEventType,
type ToolbarAction,
type ToolbarActionGroup,
type ToolbarContext,
type ToolbarModuleConfig,
ToolbarModuleExtension,
} from '@blocksuite/affine-shared/services';
import { getBlockProps } from '@blocksuite/affine-shared/utils';
import { BlockSelection } from '@blocksuite/block-std';
import { BlockFlavourIdentifier, BlockSelection } from '@blocksuite/block-std';
import { Bound } from '@blocksuite/global/gfx';
import {
CaptionIcon,
CopyIcon,
@@ -18,8 +31,8 @@ import {
DuplicateIcon,
ResetIcon,
} from '@blocksuite/icons/lit';
import { Slice, Text } from '@blocksuite/store';
import { signal } from '@preact/signals-core';
import { type ExtensionType, Slice, Text } from '@blocksuite/store';
import { computed, signal } from '@preact/signals-core';
import { html } from 'lit';
import { keyed } from 'lit/directives/keyed.js';
import * as Y from 'yjs';
@@ -27,26 +40,62 @@ import * as Y from 'yjs';
import { BookmarkBlockComponent } from '../bookmark-block';
const trackBaseProps = {
segment: 'doc',
page: 'doc editor',
module: 'toolbar',
category: 'bookmark',
type: 'card view',
};
export const builtinToolbarConfig = {
const previewAction = {
id: 'a.preview',
content(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return null;
const { url } = model.props;
return html`<affine-link-preview .url=${url}></affine-link-preview>`;
},
} satisfies ToolbarAction;
const captionAction = {
id: 'd.caption',
tooltip: 'Caption',
icon: CaptionIcon(),
run(ctx) {
const block = ctx.getCurrentBlockByType(BookmarkBlockComponent);
block?.captionEditor?.show();
ctx.track('OpenedCaptionEditor', {
...trackBaseProps,
control: 'add caption',
});
},
} satisfies ToolbarAction;
const createOnToggleFn =
(
ctx: ToolbarContext,
name: Extract<
LinkEventType,
| 'OpenedViewSelector'
| 'OpenedCardStyleSelector'
| 'OpenedCardScaleSelector'
>,
control: string
) =>
(e: CustomEvent<boolean>) => {
e.stopPropagation();
const opened = e.detail;
if (!opened) return;
ctx.track(name, {
...trackBaseProps,
control,
});
};
const builtinToolbarConfig = {
actions: [
{
id: 'a.preview',
content(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return null;
const { url } = model.props;
return html`<affine-link-preview .url=${url}></affine-link-preview>`;
},
},
previewAction,
{
id: 'b.conversions',
actions: [
@@ -181,15 +230,12 @@ export const builtinToolbarConfig = {
if (!model) return null;
const actions = this.actions.map(action => ({ ...action }));
const onToggle = (e: CustomEvent<boolean>) => {
const opened = e.detail;
if (!opened) return;
ctx.track('OpenedViewSelector', {
...trackBaseProps,
control: 'switch view',
});
};
const viewType$ = signal(actions[1].label);
const onToggle = createOnToggleFn(
ctx,
'OpenedViewSelector',
'switch view'
);
return html`${keyed(
model,
@@ -197,7 +243,7 @@ export const builtinToolbarConfig = {
@toggle=${onToggle}
.actions=${actions}
.context=${ctx}
.viewType$=${signal(actions[1].label)}
.viewType$=${viewType$}
></affine-view-dropdown-menu>`
)}`;
},
@@ -230,16 +276,11 @@ export const builtinToolbarConfig = {
});
},
})) satisfies ToolbarAction[];
const onToggle = (e: CustomEvent<boolean>) => {
const opened = e.detail;
if (!opened) return;
ctx.track('OpenedCardStyleSelector', {
...trackBaseProps,
control: 'switch card style',
});
};
const onToggle = createOnToggleFn(
ctx,
'OpenedCardStyleSelector',
'switch card style'
);
return html`${keyed(
model,
@@ -252,20 +293,7 @@ export const builtinToolbarConfig = {
)}`;
},
} satisfies ToolbarActionGroup<ToolbarAction>,
{
id: 'd.caption',
tooltip: 'Caption',
icon: CaptionIcon(),
run(ctx) {
const block = ctx.getCurrentBlockByType(BookmarkBlockComponent);
block?.captionEditor?.show();
ctx.track('OpenedCaptionEditor', {
...trackBaseProps,
control: 'add caption',
});
},
},
captionAction,
{
placement: ActionPlacement.More,
id: 'a.clipboard',
@@ -331,3 +359,235 @@ export const builtinToolbarConfig = {
},
],
} as const satisfies ToolbarModuleConfig;
const builtinSurfaceToolbarConfig = {
actions: [
previewAction,
{
id: 'b.conversions',
actions: [
{
id: 'card',
label: 'Card view',
disabled: true,
},
{
id: 'embed',
label: 'Embed view',
run(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return;
const { id: oldId, xywh, parent } = model;
const { url, caption } = model.props;
const options = ctx.std
.get(EmbedOptionProvider)
.getEmbedBlockOptions(url);
if (options?.viewType !== 'embed') return;
const { flavour, styles } = options;
let { style } = model.props;
if (!styles.includes(style)) {
style = styles[0];
}
const bounds = Bound.deserialize(xywh);
bounds.w = EMBED_CARD_WIDTH[style];
bounds.h = EMBED_CARD_HEIGHT[style];
const newId = ctx.store.addBlock(
flavour,
{ url, caption, style, xywh: bounds.serialize() },
parent
);
ctx.command.exec(reassociateConnectorsCommand, { oldId, newId });
ctx.store.deleteBlock(model);
// Selects new block
ctx.gfx.selection.set({ editing: false, elements: [newId] });
ctx.track('SelectedView', {
...trackBaseProps,
control: 'select view',
type: 'embed view',
});
},
},
],
when(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return false;
const { url } = model.props;
const options = ctx.std
.get(EmbedOptionProvider)
.getEmbedBlockOptions(url);
return options?.viewType === 'embed';
},
content(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return null;
const actions = this.actions.map(action => ({ ...action }));
const viewType$ = signal('Card view');
const onToggle = createOnToggleFn(
ctx,
'OpenedViewSelector',
'switch view'
);
return html`${keyed(
model,
html`<affine-view-dropdown-menu
@toggle=${onToggle}
.actions=${actions}
.context=${ctx}
.viewType$=${viewType$}
></affine-view-dropdown-menu>`
)}`;
},
} satisfies ToolbarActionGroup<ToolbarAction>,
{
id: 'b.style',
actions: [
{
id: 'horizontal',
label: 'Large horizontal style',
},
{
id: 'list',
label: 'Small horizontal style',
},
{
id: 'vertical',
label: 'Large vertical style',
},
{
id: 'cube',
label: 'Small vertical style',
},
].filter(action => BookmarkStyles.includes(action.id as EmbedCardStyle)),
content(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return null;
const actions = this.actions.map(action => ({
...action,
run: ({ store }) => {
const style = action.id as EmbedCardStyle;
const bounds = Bound.deserialize(model.xywh);
bounds.w = EMBED_CARD_WIDTH[style];
bounds.h = EMBED_CARD_HEIGHT[style];
const xywh = bounds.serialize();
store.updateBlock(model, { style, xywh });
ctx.track('SelectedCardStyle', {
...trackBaseProps,
control: 'select card style',
type: style,
});
},
})) satisfies ToolbarAction[];
const style$ = model.props.style$;
const onToggle = createOnToggleFn(
ctx,
'OpenedCardStyleSelector',
'switch card style'
);
return html`${keyed(
model,
html`<affine-card-style-dropdown-menu
@toggle=${onToggle}
.actions=${actions}
.context=${ctx}
.style$=${style$}
></affine-card-style-dropdown-menu>`
)}`;
},
} satisfies ToolbarActionGroup<ToolbarAction>,
{
...captionAction,
id: 'c.caption',
},
{
id: 'd.scale',
content(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return null;
const scale$ = computed(() => {
const {
xywh$: { value: xywh },
} = model;
const {
style$: { value: style },
} = model.props;
const bounds = Bound.deserialize(xywh);
const height = EMBED_CARD_HEIGHT[style];
return Math.round(100 * (bounds.h / height));
});
const onSelect = (e: CustomEvent<number>) => {
e.stopPropagation();
const scale = e.detail / 100;
const bounds = Bound.deserialize(model.xywh);
const style = model.props.style;
bounds.w = EMBED_CARD_WIDTH[style] * scale;
bounds.h = EMBED_CARD_HEIGHT[style] * scale;
const xywh = bounds.serialize();
ctx.store.updateBlock(model, { xywh });
ctx.track('SelectedCardScale', {
...trackBaseProps,
control: 'select card scale',
});
};
const onToggle = createOnToggleFn(
ctx,
'OpenedCardScaleSelector',
'switch card scale'
);
const format = (value: number) => `${value}%`;
return html`${keyed(
model,
html`<affine-size-dropdown-menu
@select=${onSelect}
@toggle=${onToggle}
.format=${format}
.size$=${scale$}
></affine-size-dropdown-menu>`
)}`;
},
},
],
when: ctx => ctx.getSurfaceModelsByType(BookmarkBlockModel).length === 1,
} as const satisfies ToolbarModuleConfig;
export const createBuiltinToolbarConfigExtension = (
flavour: string
): ExtensionType[] => {
const name = flavour.split(':').pop();
return [
ToolbarModuleExtension({
id: BlockFlavourIdentifier(flavour),
config: builtinToolbarConfig,
}),
ToolbarModuleExtension({
id: BlockFlavourIdentifier(`affine:surface:${name}`),
config: builtinSurfaceToolbarConfig,
}),
];
};
@@ -8,6 +8,7 @@
"include": ["./src"],
"references": [
{ "path": "../block-embed" },
{ "path": "../block-surface" },
{ "path": "../../components" },
{ "path": "../../model" },
{ "path": "../../shared" },
@@ -13,6 +13,7 @@ function format(scale: number) {
return `${scale}%`;
}
// TODO(@fundon): remove it after refacting is completed
export class EdgelessScalePanel extends LitElement {
static override styles = css`
:host {
@@ -28,7 +29,7 @@ export class EdgelessScalePanel extends LitElement {
}
.scale-input {
display: flx;
display: flex;
align-self: stretch;
border: 0.5px solid var(--affine-border-color);
border-radius: 8px;
@@ -1,11 +0,0 @@
import type { ToolbarModuleConfig } from '@blocksuite/affine-shared/services';
export const builtinBookmarkToolbarConfig = {
actions: [
{
id: 'a.test',
label: 'Bookmark',
run() {},
},
],
} as const satisfies ToolbarModuleConfig;
@@ -2,7 +2,6 @@ import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
import { BlockFlavourIdentifier } from '@blocksuite/block-std';
import type { ExtensionType } from '@blocksuite/store';
import { builtinBookmarkToolbarConfig } from './bookmark';
import { builtinBrushToolbarConfig } from './brush';
import { builtinConnectorToolbarConfig } from './connector';
import { builtinEmbedToolbarConfig } from './embed';
@@ -16,11 +15,6 @@ import { builtinShapeToolbarConfig } from './shape';
import { builtinTextToolbarConfig } from './text';
export const EdgelessElementToolbarExtension: ExtensionType[] = [
ToolbarModuleExtension({
id: BlockFlavourIdentifier('affine:surface:bookmark'),
config: builtinBookmarkToolbarConfig,
}),
ToolbarModuleExtension({
id: BlockFlavourIdentifier('affine:surface:image'),
config: builtinImageToolbarConfig,
+2 -1
View File
@@ -65,7 +65,8 @@
"./view-dropdown-menu": "./src/view-dropdown-menu/index.ts",
"./card-style-dropdown-menu": "./src/card-style-dropdown-menu/index.ts",
"./highlight-dropdown-menu": "./src/highlight-dropdown-menu/index.ts",
"./tooltip-content-with-shortcut": "./src/tooltip-content-with-shortcut/index.ts"
"./tooltip-content-with-shortcut": "./src/tooltip-content-with-shortcut/index.ts",
"./size-dropdown-menu": "./src/size-dropdown-menu/index.ts"
},
"files": [
"src",
@@ -3,11 +3,7 @@ import {
type ToolbarAction,
ToolbarContext,
} from '@blocksuite/affine-shared/services';
import {
PropTypes,
requiredProperties,
ShadowlessElement,
} from '@blocksuite/block-std';
import { PropTypes, requiredProperties } from '@blocksuite/block-std';
import { SignalWatcher } from '@blocksuite/global/lit';
import { PaletteIcon } from '@blocksuite/icons/lit';
import {
@@ -15,6 +11,7 @@ import {
type ReadonlySignal,
type Signal,
} from '@preact/signals-core';
import { LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { html, type TemplateResult } from 'lit-html';
import { ifDefined } from 'lit-html/directives/if-defined.js';
@@ -24,23 +21,29 @@ import {
EmbedCardDarkCubeIcon,
EmbedCardDarkHorizontalIcon,
EmbedCardDarkListIcon,
EmbedCardDarkVerticalIcon,
EmbedCardLightCubeIcon,
EmbedCardLightHorizontalIcon,
EmbedCardLightListIcon,
EmbedCardLightVerticalIcon,
} from '../icons';
const cardStyleMap: Record<ColorScheme, Record<string, TemplateResult>> = {
light: {
cube: EmbedCardLightCubeIcon,
cubeThick: EmbedCardLightCubeIcon,
horizontal: EmbedCardLightHorizontalIcon,
horizontalThin: EmbedCardLightListIcon,
list: EmbedCardLightListIcon,
cubeThick: EmbedCardLightCubeIcon,
vertical: EmbedCardLightVerticalIcon,
},
dark: {
cube: EmbedCardDarkCubeIcon,
cubeThick: EmbedCardDarkCubeIcon,
horizontal: EmbedCardDarkHorizontalIcon,
horizontalThin: EmbedCardDarkListIcon,
list: EmbedCardDarkListIcon,
cubeThick: EmbedCardDarkCubeIcon,
vertical: EmbedCardDarkVerticalIcon,
},
};
@@ -49,7 +52,7 @@ const cardStyleMap: Record<ColorScheme, Record<string, TemplateResult>> = {
context: PropTypes.instanceOf(ToolbarContext),
style$: PropTypes.object,
})
export class CardStyleDropdownMenu extends SignalWatcher(ShadowlessElement) {
export class CardStyleDropdownMenu extends SignalWatcher(LitElement) {
@property({ attribute: false })
accessor actions!: ToolbarAction[];
@@ -0,0 +1,183 @@
import { stopPropagation } from '@blocksuite/affine-shared/utils';
import { PropTypes, requiredProperties } from '@blocksuite/block-std';
import { SignalWatcher } from '@blocksuite/global/lit';
import { ArrowDownSmallIcon, DoneIcon } from '@blocksuite/icons/lit';
import type { ReadonlySignal, Signal } from '@preact/signals-core';
import { css, html, LitElement } from 'lit';
import { property, query } from 'lit/decorators.js';
import { repeat } from 'lit-html/directives/repeat.js';
import { when } from 'lit-html/directives/when.js';
import clamp from 'lodash-es/clamp';
import type { EditorMenuButton } from '../toolbar';
type SizeItem = { key?: string | number; value: number };
const MIN_SIZE = 0;
const MAX_SIZE = 400;
const SIZE_LIST: SizeItem[] = [
{ value: 50 },
{ value: 100 },
{ value: 200 },
] as const;
@requiredProperties({
size$: PropTypes.object,
})
export class SizeDropdownMenu extends SignalWatcher(LitElement) {
static override styles = css`
div[data-orientation] {
width: 68px;
gap: 4px;
min-width: unset;
overflow: unset;
}
editor-menu-action {
justify-content: space-between;
}
:host([data-type='check']) editor-menu-action[data-selected] {
color: var(--affine-primary-color);
background-color: none;
}
input {
display: flex;
align-self: stretch;
border: 0.5px solid var(--affine-border-color);
border-radius: 8px;
padding: 4px 8px;
box-sizing: border-box;
}
input:focus {
outline-color: var(--affine-primary-color);
outline-width: 0.5px;
}
input::placeholder {
color: var(--affine-placeholder-color);
}
`;
@property({ attribute: false })
accessor sizes: readonly SizeItem[] = SIZE_LIST;
@property({ attribute: false })
accessor size$!: Signal<number> | ReadonlySignal<number>;
@property({ attribute: false })
accessor maxSize: number = MAX_SIZE;
@property({ attribute: false })
accessor minSize: number = MIN_SIZE;
@property({ attribute: false })
accessor format: ((e: number) => string) | undefined;
@property({ attribute: 'data-type' })
accessor type: 'normal' | 'check' = 'normal';
clamp(value: number, min = this.minSize, max = this.maxSize) {
return clamp(value, min, max);
}
select(value: number) {
const detail = this.clamp(value);
this.dispatchEvent(new CustomEvent('select', { detail }));
}
private readonly _onKeydown = (e: KeyboardEvent) => {
e.stopPropagation();
if (e.isComposing) return;
if (e.key !== 'Enter') return;
e.preventDefault();
const input = e.target as HTMLInputElement;
const value = parseInt(input.value.trim());
// Handle edge case where user enters a non-number
if (isNaN(value)) {
input.value = '';
return;
}
// Handle edge case when user enters a number that is out of range
this.select(value);
input.value = '';
this.menuButton.hide();
};
@query('editor-menu-button')
accessor menuButton!: EditorMenuButton;
override render() {
const {
sizes,
format,
type,
size$: { value: size },
} = this;
const isCheckType = type === 'check';
const placeholder = format?.(Math.trunc(size)) ?? Math.trunc(size);
return html`
<editor-menu-button
.contentPadding="${'8px'}"
.button=${html`
<editor-icon-button
aria-label="Scale"
.tooltip="${'Scale'}"
.justify="${'space-between'}"
.labelHeight="${'20px'}"
.iconContainerWidth="${'65px'}"
>
<span class="label">${format?.(size) ?? size}</span>
${ArrowDownSmallIcon()}
</editor-icon-button>
`}
>
<div data-orientation="vertical">
${repeat(
sizes,
({ key, value }) => key ?? value,
({ key, value }) => html`
<editor-menu-action
aria-label="${key}"
?data-selected="${size === value}"
@click=${() => this.select(value)}
>
${key ?? format?.(value) ?? value}
${when(isCheckType && size === value, () => DoneIcon())}
</editor-menu-action>
`
)}
<input
type="text"
inputmode="numeric"
pattern="[0-9]*"
min="${this.minSize}"
max="${this.maxSize}"
placeholder="${placeholder}"
@keydown=${this._onKeydown}
@input=${stopPropagation}
@click=${stopPropagation}
@pointerdown=${stopPropagation}
@cut=${stopPropagation}
@copy=${stopPropagation}
@paste=${stopPropagation}
/>
</div>
</editor-menu-button>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'affine-size-dropdown-menu': SizeDropdownMenu;
}
}
@@ -0,0 +1,7 @@
import { SizeDropdownMenu } from './dropdown-menu';
export * from './dropdown-menu';
export function effects() {
customElements.define('affine-size-dropdown-menu', SizeDropdownMenu);
}
@@ -2,14 +2,11 @@ import {
type ToolbarAction,
ToolbarContext,
} from '@blocksuite/affine-shared/services';
import {
PropTypes,
requiredProperties,
ShadowlessElement,
} from '@blocksuite/block-std';
import { PropTypes, requiredProperties } from '@blocksuite/block-std';
import { SignalWatcher } from '@blocksuite/global/lit';
import { ArrowDownSmallIcon } from '@blocksuite/icons/lit';
import type { ReadonlySignal, Signal } from '@preact/signals-core';
import { LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { html } from 'lit-html';
import { ifDefined } from 'lit-html/directives/if-defined.js';
@@ -20,7 +17,7 @@ import { repeat } from 'lit-html/directives/repeat.js';
context: PropTypes.instanceOf(ToolbarContext),
viewType$: PropTypes.object,
})
export class ViewDropdownMenu extends SignalWatcher(ShadowlessElement) {
export class ViewDropdownMenu extends SignalWatcher(LitElement) {
@property({ attribute: false })
accessor actions!: ToolbarAction[];
@@ -43,6 +40,7 @@ export class ViewDropdownMenu extends SignalWatcher(ShadowlessElement) {
.button=${html`
<editor-icon-button
aria-label="Switch view"
.tooltip="${'Switch view'}"
.justify="${'space-between'}"
.labelHeight="${'20px'}"
.iconContainerWidth="${'110px'}"
@@ -425,8 +425,6 @@ function createExternalLinkableToolbarConfig(
toast(ctx.host, 'Copied link to clipboard');
ctx.track('CopiedLink', {
segment: 'doc',
page: 'doc editor',
module: 'toolbar',
category: matchModels(model, [BookmarkBlockModel])
? 'bookmark'
@@ -464,8 +462,6 @@ function createExternalLinkableToolbarConfig(
);
ctx.track('OpenedAliasPopup', {
segment: 'doc',
page: 'doc editor',
module: 'toolbar',
category: matchModels(model, [BookmarkBlockModel])
? 'bookmark'
@@ -986,6 +982,11 @@ export const createCustomToolbarExtension = (
config: createExternalLinkableToolbarConfig(BookmarkBlockComponent),
}),
ToolbarModuleExtension({
id: BlockFlavourIdentifier('custom:affine:surface:bookmark'),
config: createExternalLinkableToolbarConfig(BookmarkBlockComponent),
}),
ToolbarModuleExtension({
id: BlockFlavourIdentifier('custom:affine:embed-figma'),
config: createExternalLinkableToolbarConfig(EmbedFigmaBlockComponent),
+1
View File
@@ -69,6 +69,7 @@ export const PackageList = [
name: '@blocksuite/affine-block-bookmark',
workspaceDependencies: [
'blocksuite/affine/blocks/block-embed',
'blocksuite/affine/blocks/block-surface',
'blocksuite/affine/components',
'blocksuite/affine/model',
'blocksuite/affine/shared',
+1
View File
@@ -2338,6 +2338,7 @@ __metadata:
resolution: "@blocksuite/affine-block-bookmark@workspace:blocksuite/affine/blocks/block-bookmark"
dependencies:
"@blocksuite/affine-block-embed": "workspace:*"
"@blocksuite/affine-block-surface": "workspace:*"
"@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-model": "workspace:*"
"@blocksuite/affine-shared": "workspace:*"