refactor(editor): adjust folder structure for slash menu extension (#10588)

Close [BS-2743](https://linear.app/affine-design/issue/BS-2743/slash-menu插件化:调整文件夹结构)

This PR move slash menu from `affine-root-block` to `widget-affine-slash-menu`, and make it as a `WidgetViewExtension`
This commit is contained in:
L-Sun
2025-03-06 16:12:06 +00:00
parent 289d3cd20e
commit 62d8c0c7cb
73 changed files with 397 additions and 230 deletions
@@ -36,6 +36,7 @@
"@blocksuite/affine-widget-frame-title": "workspace:*",
"@blocksuite/affine-widget-remote-selection": "workspace:*",
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*",
"@blocksuite/affine-widget-slash-menu": "workspace:*",
"@blocksuite/affine-widget-toolbar": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/data-view": "workspace:*",
@@ -12,6 +12,7 @@ import {
import { dragHandleWidget } from '@blocksuite/affine-widget-drag-handle';
import { docRemoteSelectionWidget } from '@blocksuite/affine-widget-remote-selection';
import { scrollAnchoringWidget } from '@blocksuite/affine-widget-scroll-anchoring';
import { SlashMenuExtension } from '@blocksuite/affine-widget-slash-menu';
import { toolbarWidget } from '@blocksuite/affine-widget-toolbar';
import {
BlockFlavourIdentifier,
@@ -25,7 +26,6 @@ import {
innerModalWidget,
linkedDocWidget,
modalWidget,
slashMenuWidget,
viewportOverlayWidget,
} from './widgets';
@@ -42,7 +42,7 @@ export const CommonSpecs: ExtensionType[] = [
modalWidget,
innerModalWidget,
slashMenuWidget,
SlashMenuExtension,
linkedDocWidget,
dragHandleWidget,
docRemoteSelectionWidget,
@@ -4,7 +4,6 @@ import { literal, unsafeStatic } from 'lit/static-html.js';
import { AFFINE_INNER_MODAL_WIDGET } from '../widgets/inner-modal/inner-modal.js';
import { AFFINE_LINKED_DOC_WIDGET } from '../widgets/linked-doc/config.js';
import { AFFINE_MODAL_WIDGET } from '../widgets/modal/modal.js';
import { AFFINE_SLASH_MENU_WIDGET } from '../widgets/slash-menu/index.js';
import { AFFINE_VIEWPORT_OVERLAY_WIDGET } from '../widgets/viewport-overlay/viewport-overlay.js';
export const modalWidget = WidgetViewExtension(
@@ -17,11 +16,6 @@ export const innerModalWidget = WidgetViewExtension(
AFFINE_INNER_MODAL_WIDGET,
literal`${unsafeStatic(AFFINE_INNER_MODAL_WIDGET)}`
);
export const slashMenuWidget = WidgetViewExtension(
'affine:page',
AFFINE_SLASH_MENU_WIDGET,
literal`${unsafeStatic(AFFINE_SLASH_MENU_WIDGET)}`
);
export const linkedDocWidget = WidgetViewExtension(
'affine:page',
AFFINE_LINKED_DOC_WIDGET,
@@ -106,14 +106,6 @@ import {
AFFINE_PAGE_DRAGGING_AREA_WIDGET,
AffinePageDraggingAreaWidget,
} from './widgets/page-dragging-area/page-dragging-area.js';
import {
AFFINE_SLASH_MENU_WIDGET,
AffineSlashMenuWidget,
} from './widgets/slash-menu/index.js';
import {
InnerSlashMenu,
SlashMenu,
} from './widgets/slash-menu/slash-menu-popover.js';
import {
AFFINE_SURFACE_REF_TOOLBAR,
AffineSurfaceRefToolbar,
@@ -156,7 +148,6 @@ function registerWidgets() {
AffinePageDraggingAreaWidget
);
customElements.define(AFFINE_IMAGE_TOOLBAR_WIDGET, AffineImageToolbarWidget);
customElements.define(AFFINE_SLASH_MENU_WIDGET, AffineSlashMenuWidget);
customElements.define(
AFFINE_VIEWPORT_OVERLAY_WIDGET,
AffineViewportOverlayWidget
@@ -274,8 +265,6 @@ function registerEdgelessEditorComponents() {
function registerMiscComponents() {
// Modal and menu components
customElements.define('affine-custom-modal', AffineCustomModal);
customElements.define('affine-slash-menu', SlashMenu);
customElements.define('inner-slash-menu', InnerSlashMenu);
// Loading and preview components
customElements.define('loader-element', Loader);
+1 -1
View File
@@ -4,6 +4,7 @@ import type {
AFFINE_DOC_REMOTE_SELECTION_WIDGET,
AFFINE_EDGELESS_REMOTE_SELECTION_WIDGET,
} from '@blocksuite/affine-widget-remote-selection';
import type { AFFINE_SLASH_MENU_WIDGET } from '@blocksuite/affine-widget-slash-menu';
import type { EdgelessRootBlockComponent } from './edgeless/edgeless-root-block.js';
import type { PageRootBlockComponent } from './page/page-root-block.js';
@@ -14,7 +15,6 @@ import type { AFFINE_INNER_MODAL_WIDGET } from './widgets/inner-modal/inner-moda
import type { AFFINE_LINKED_DOC_WIDGET } from './widgets/linked-doc/config.js';
import type { AFFINE_MODAL_WIDGET } from './widgets/modal/modal.js';
import type { AFFINE_PAGE_DRAGGING_AREA_WIDGET } from './widgets/page-dragging-area/page-dragging-area.js';
import type { AFFINE_SLASH_MENU_WIDGET } from './widgets/slash-menu/index.js';
import type { AFFINE_VIEWPORT_OVERLAY_WIDGET } from './widgets/viewport-overlay/viewport-overlay.js';
export type PageRootBlockWidgetName =
@@ -1,3 +1,4 @@
// TODO(@L-Sun): remove these utils
export function formatDate(date: Date) {
// yyyy-mm-dd
const year = date.getFullYear();
@@ -21,15 +21,6 @@ export {
export { AffineLinkedDocWidget } from './linked-doc/index.js';
export { AffineModalWidget } from './modal/modal.js';
export { AffinePageDraggingAreaWidget } from './page-dragging-area/page-dragging-area.js';
export {
type AffineSlashMenuActionItem,
type AffineSlashMenuContext,
type AffineSlashMenuGroupDivider,
type AffineSlashMenuItem,
type AffineSlashMenuItemGenerator,
AffineSlashMenuWidget,
type AffineSlashSubMenu,
} from './slash-menu/index.js';
export { AffineSurfaceRefToolbar } from './surface-ref-toolbar/surface-ref-toolbar.js';
export * from './viewport-overlay/viewport-overlay.js';
export { AffineFrameTitleWidget } from '@blocksuite/affine-widget-frame-title';
@@ -8,6 +8,7 @@ import { unsafeCSSVar } from '@blocksuite/affine-shared/theme';
import {
createKeydownObserver,
getCurrentNativeRange,
getPopperPosition,
getViewportElement,
} from '@blocksuite/affine-shared/utils';
import { PropTypes, requiredProperties } from '@blocksuite/block-std';
@@ -20,7 +21,6 @@ import { property, query, queryAll, state } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import throttle from 'lodash-es/throttle';
import { getPopperPosition } from '../../utils/position.js';
import type { LinkedDocContext, LinkedMenuGroup } from './config.js';
import { linkedDocPopoverStyles } from './styles.js';
import { resolveSignal } from './utils.js';
@@ -30,6 +30,7 @@
{ "path": "../widget-frame-title" },
{ "path": "../widget-remote-selection" },
{ "path": "../widget-scroll-anchoring" },
{ "path": "../widget-slash-menu" },
{ "path": "../widget-toolbar" },
{ "path": "../../framework/block-std" },
{ "path": "../data-view" },
@@ -14,6 +14,7 @@ export * from './insert';
export * from './is-abort-error';
export * from './math';
export * from './model';
export * from './popper-position';
export * from './print-to-pdf';
export * from './reference';
export * from './reordering';
@@ -18,7 +18,7 @@ type CollisionBox = {
edgeGap?: number;
};
export function calcSafeCoordinate({
function calcSafeCoordinate({
positioningPoint,
objRect = { width: 0, height: 0 },
boundaryRect = document.body.getBoundingClientRect(),
@@ -50,7 +50,7 @@ export function calcSafeCoordinate({
*
* Please give preference to {@link getPopperPosition}
*/
export function compareTopAndBottomSpace(
function compareTopAndBottomSpace(
obj: { getBoundingClientRect: () => DOMRect },
container = document.body,
gap = 20
@@ -0,0 +1 @@
# widget-slash-menu
@@ -0,0 +1,51 @@
{
"name": "@blocksuite/affine-widget-slash-menu",
"description": "Affine slash menu widget.",
"type": "module",
"scripts": {
"build": "tsc",
"test:unit": "nx vite:test --run --passWithNoTests",
"test:unit:coverage": "nx vite:test --run --coverage",
"test:e2e": "playwright test"
},
"sideEffects": false,
"keywords": [],
"author": "toeverything",
"license": "MIT",
"dependencies": {
"@blocksuite/affine-block-attachment": "workspace:*",
"@blocksuite/affine-block-database": "workspace:*",
"@blocksuite/affine-block-embed": "workspace:*",
"@blocksuite/affine-block-image": "workspace:*",
"@blocksuite/affine-block-latex": "workspace:*",
"@blocksuite/affine-block-note": "workspace:*",
"@blocksuite/affine-block-surface": "workspace:*",
"@blocksuite/affine-block-surface-ref": "workspace:*",
"@blocksuite/affine-block-table": "workspace:*",
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/data-view": "workspace:*",
"@blocksuite/global": "workspace:*",
"@blocksuite/icons": "^2.2.4",
"@blocksuite/inline": "workspace:*",
"@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.13",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.12",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21"
},
"exports": {
".": "./src/index.ts",
"./effects": "./src/effects.ts"
},
"files": [
"src",
"dist",
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.20.0"
}
@@ -57,8 +57,8 @@ import {
createDefaultDoc,
openFileOrFiles,
} from '@blocksuite/affine-shared/utils';
import type { BlockStdScope } from '@blocksuite/block-std';
import { viewPresets } from '@blocksuite/data-view/view-presets';
import { assertType } from '@blocksuite/global/utils';
import {
DualLinkIcon,
ExportToPdfIcon,
@@ -74,16 +74,15 @@ import type { BlockModel } from '@blocksuite/store';
import { Slice, Text } from '@blocksuite/store';
import type { TemplateResult } from 'lit';
import type { RootBlockComponent } from '../../types.js';
import { formatDate, formatTime } from '../../utils/misc.js';
import type { AffineLinkedDocWidget } from '../linked-doc/index.js';
import { type SlashMenuTooltip, slashMenuToolTips } from './tooltips/index.js';
import { type SlashMenuTooltip, slashMenuToolTips } from './tooltips';
import {
createConversionItem,
createTextFormatItem,
formatDate,
formatTime,
insideEdgelessText,
tryRemoveEmptyLine,
} from './utils.js';
} from './utils';
export type SlashMenuConfig = {
triggerKeys: string[];
@@ -136,7 +135,7 @@ export type SlashMenuItemGenerator = (
) => (SlashMenuGroupDivider | SlashMenuActionItem | SlashSubMenu)[];
export type SlashMenuContext = {
rootComponent: RootBlockComponent;
std: BlockStdScope;
model: BlockModel;
};
@@ -183,7 +182,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
showWhen: ({ model }) => {
return model.doc.get(FeatureFlagService).getFlag('enable_callout');
},
action: ({ model, rootComponent }) => {
action: ({ model, std }) => {
const { doc } = model;
const parent = doc.getParent(model);
if (!parent) return;
@@ -194,11 +193,11 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
if (!calloutId) return;
const paragraphId = doc.addBlock('affine:paragraph', {}, calloutId);
if (!paragraphId) return;
rootComponent.updateComplete
std.host.updateComplete
.then(() => {
const paragraph = rootComponent.std.view.getBlock(paragraphId);
const paragraph = std.view.getBlock(paragraphId);
if (!paragraph) return;
rootComponent.std.command.exec(focusBlockEnd, {
std.command.exec(focusBlockEnd, {
focusBlock: paragraph,
});
})
@@ -211,8 +210,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
description: 'Create a equation block.',
icon: TeXIcon(),
alias: ['inlineMath, inlineEquation', 'inlineLatex'],
action: ({ rootComponent }) => {
rootComponent.std.command
action: ({ std }) => {
std.command
.chain()
.pipe(getTextSelectionCommand)
.pipe(insertInlineLatex)
@@ -245,9 +244,9 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
tooltip: slashMenuToolTips['New Doc'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-linked-doc'),
action: ({ rootComponent, model }) => {
const newDoc = createDefaultDoc(rootComponent.doc.workspace);
insertContent(rootComponent.host, model, REFERENCE_NODE, {
action: ({ std, model }) => {
const newDoc = createDefaultDoc(std.host.doc.workspace);
insertContent(std.host, model, REFERENCE_NODE, {
reference: {
type: 'LinkedPage',
pageId: newDoc.id,
@@ -261,33 +260,36 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
icon: LinkedDocIcon,
tooltip: slashMenuToolTips['Linked Doc'],
alias: ['dual link'],
showWhen: ({ rootComponent, model }) => {
const { std } = rootComponent;
showWhen: ({ std, model }) => {
const root = model.doc.root;
if (!root) return false;
const linkedDocWidget = std.view.getWidget(
'affine-linked-doc-widget',
rootComponent.model.id
root.id
);
if (!linkedDocWidget) return false;
return model.doc.schema.flavourSchemaMap.has('affine:embed-linked-doc');
},
action: ({ model, rootComponent }) => {
const { std } = rootComponent;
action: ({ model, std }) => {
const root = model.doc.root;
if (!root) return;
const linkedDocWidget = std.view.getWidget(
'affine-linked-doc-widget',
rootComponent.model.id
root.id
);
if (!linkedDocWidget) return;
assertType<AffineLinkedDocWidget>(linkedDocWidget);
// TODO(@L-Sun): make linked-doc-widget as extension
// @ts-expect-error same as above
const triggerKey = linkedDocWidget.config.triggerKeys[0];
insertContent(rootComponent.host, model, triggerKey);
insertContent(std.host, model, triggerKey);
const inlineEditor = getInlineEditorByModel(rootComponent.host, model);
const inlineEditor = getInlineEditorByModel(std.host, model);
// Wait for range to be updated
inlineEditor?.slots.inlineRangeSync.once(() => {
// TODO(@L-Sun): make linked-doc-widget as extension
// @ts-expect-error same as above
linkedDocWidget.show({ addTriggerKey: true });
});
},
@@ -301,8 +303,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
icon: TableIcon(),
tooltip: slashMenuToolTips['Table View'],
showWhen: ({ model }) => !insideEdgelessText(model),
action: ({ rootComponent }) => {
rootComponent.std.command
action: ({ std }) => {
std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(insertTableBlockCommand, {
@@ -311,8 +313,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
})
.pipe(({ insertedTableBlockId }) => {
if (insertedTableBlockId) {
const telemetry =
rootComponent.std.getOptional(TelemetryProvider);
const telemetry = std.getOptional(TelemetryProvider);
telemetry?.track('BlockCreated', {
blockType: 'affine:table',
});
@@ -328,8 +329,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
tooltip: slashMenuToolTips['Image'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:image'),
action: async ({ rootComponent }) => {
const [success, ctx] = rootComponent.std.command
action: async ({ std }) => {
const [success, ctx] = std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(insertImagesCommand, { removeEmptyLine: true })
@@ -345,14 +346,15 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
tooltip: slashMenuToolTips['Link'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:bookmark'),
action: async ({ rootComponent, model }) => {
const parentModel = rootComponent.doc.getParent(model);
action: async ({ std, model }) => {
const { host } = std;
const parentModel = host.doc.getParent(model);
if (!parentModel) {
return;
}
const index = parentModel.children.indexOf(model) + 1;
await toggleEmbedCardCreateModal(
rootComponent.host,
host,
'Links',
'The added link will be displayed as a card view.',
{ mode: 'page', parentModel, index }
@@ -368,19 +370,13 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
alias: ['file'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:attachment'),
action: async ({ rootComponent, model }) => {
action: async ({ std, model }) => {
const file = await openFileOrFiles();
if (!file) return;
const maxFileSize =
rootComponent.std.store.get(FileSizeLimitService).maxFileSize;
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
await addSiblingAttachmentBlocks(
rootComponent.host,
[file],
maxFileSize,
model
);
await addSiblingAttachmentBlocks(std.host, [file], maxFileSize, model);
tryRemoveEmptyLine(model);
},
},
@@ -391,15 +387,14 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
tooltip: slashMenuToolTips['PDF'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:attachment'),
action: async ({ rootComponent, model }) => {
action: async ({ std, model }) => {
const file = await openFileOrFiles();
if (!file) return;
const maxFileSize =
rootComponent.std.store.get(FileSizeLimitService).maxFileSize;
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
await addSiblingAttachmentBlocks(
rootComponent.host,
std.host,
[file],
maxFileSize,
model,
@@ -416,14 +411,15 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
tooltip: slashMenuToolTips['YouTube'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-youtube'),
action: async ({ rootComponent, model }) => {
const parentModel = rootComponent.doc.getParent(model);
action: async ({ std, model }) => {
const { host } = std;
const parentModel = host.doc.getParent(model);
if (!parentModel) {
return;
}
const index = parentModel.children.indexOf(model) + 1;
await toggleEmbedCardCreateModal(
rootComponent.host,
host,
'YouTube',
'The added YouTube video link will be displayed as an embed view.',
{ mode: 'page', parentModel, index }
@@ -438,14 +434,15 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
tooltip: slashMenuToolTips['Github'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-github'),
action: async ({ rootComponent, model }) => {
const parentModel = rootComponent.doc.getParent(model);
action: async ({ std, model }) => {
const { host } = std;
const parentModel = host.doc.getParent(model);
if (!parentModel) {
return;
}
const index = parentModel.children.indexOf(model) + 1;
await toggleEmbedCardCreateModal(
rootComponent.host,
host,
'GitHub',
'The added GitHub issue or pull request link will be displayed as a card view.',
{ mode: 'page', parentModel, index }
@@ -462,14 +459,15 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
tooltip: slashMenuToolTips['Figma'],
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-figma'),
action: async ({ rootComponent, model }) => {
const parentModel = rootComponent.doc.getParent(model);
action: async ({ std, model }) => {
const { host } = std;
const parentModel = host.doc.getParent(model);
if (!parentModel) {
return;
}
const index = parentModel.children.indexOf(model) + 1;
await toggleEmbedCardCreateModal(
rootComponent.host,
host,
'Figma',
'The added Figma link will be displayed as an embed view.',
{ mode: 'page', parentModel, index }
@@ -483,14 +481,15 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
icon: LoomIcon,
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-loom'),
action: async ({ rootComponent, model }) => {
const parentModel = rootComponent.doc.getParent(model);
action: async ({ std, model }) => {
const { host } = std;
const parentModel = host.doc.getParent(model);
if (!parentModel) {
return;
}
const index = parentModel.children.indexOf(model) + 1;
await toggleEmbedCardCreateModal(
rootComponent.host,
host,
'Loom',
'The added Loom video link will be displayed as an embed view.',
{ mode: 'page', parentModel, index }
@@ -504,8 +503,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
description: 'Create a equation block.',
icon: TeXIcon(),
alias: ['mathBlock, equationBlock', 'latexBlock'],
action: ({ rootComponent }) => {
rootComponent.std.command
action: ({ std }) => {
std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(insertLatexBlockCommand, {
@@ -519,24 +518,24 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
// TODO(@L-Sun): Linear
// ---------------------------------------------------------
({ model, rootComponent }) => {
const { doc } = rootComponent;
({ model, std }) => {
const { host } = std;
const surfaceModel = getSurfaceBlock(doc);
const surfaceModel = getSurfaceBlock(host.doc);
if (!surfaceModel) return [];
const parent = doc.getParent(model);
const parent = host.doc.getParent(model);
if (!parent) return [];
const frameModels = doc
const frameModels = host.doc
.getBlocksByFlavour('affine:frame')
.map(block => block.model as FrameBlockModel);
const frameItems = frameModels.map<SlashMenuActionItem>(frameModel => ({
name: 'Frame: ' + frameModel.title,
icon: FrameIcon(),
action: ({ rootComponent }) => {
rootComponent.std.command
action: ({ std }) => {
std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(insertSurfaceRefBlockCommand, {
@@ -553,7 +552,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
name: 'Group: ' + group.title.toString(),
icon: GroupingIcon(),
action: () => {
rootComponent.std.command
std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(insertSurfaceRefBlockCommand, {
@@ -594,8 +593,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
icon: TodayIcon,
tooltip: slashMenuToolTips['Today'],
description: formatDate(now),
action: ({ rootComponent, model }) => {
insertContent(rootComponent.host, model, formatDate(now));
action: ({ std, model }) => {
insertContent(std.host, model, formatDate(now));
},
},
{
@@ -603,10 +602,10 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
icon: TomorrowIcon,
tooltip: slashMenuToolTips['Tomorrow'],
description: formatDate(tomorrow),
action: ({ rootComponent, model }) => {
action: ({ std, model }) => {
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
insertContent(rootComponent.host, model, formatDate(tomorrow));
insertContent(std.host, model, formatDate(tomorrow));
},
},
{
@@ -614,10 +613,10 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
icon: YesterdayIcon,
tooltip: slashMenuToolTips['Yesterday'],
description: formatDate(yesterday),
action: ({ rootComponent, model }) => {
action: ({ std, model }) => {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
insertContent(rootComponent.host, model, formatDate(yesterday));
insertContent(std.host, model, formatDate(yesterday));
},
},
{
@@ -625,8 +624,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
icon: NowIcon,
tooltip: slashMenuToolTips['Now'],
description: formatTime(now),
action: ({ rootComponent, model }) => {
insertContent(rootComponent.host, model, formatTime(now));
action: ({ std, model }) => {
insertContent(std.host, model, formatTime(now));
},
},
];
@@ -643,8 +642,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:database') &&
!insideEdgelessText(model),
action: ({ rootComponent }) => {
rootComponent.std.command
action: ({ std }) => {
std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(insertDatabaseBlockCommand, {
@@ -654,8 +653,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
})
.pipe(({ insertedDatabaseBlockId }) => {
if (insertedDatabaseBlockId) {
const telemetry =
rootComponent.std.getOptional(TelemetryProvider);
const telemetry = std.getOptional(TelemetryProvider);
telemetry?.track('BlockCreated', {
blockType: 'affine:database',
});
@@ -674,21 +672,22 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
!insideEdgelessText(model) &&
!!model.doc.get(FeatureFlagService).getFlag('enable_block_query'),
action: ({ model, rootComponent }) => {
const parent = rootComponent.doc.getParent(model);
action: ({ model, std }) => {
const { host } = std;
const parent = host.doc.getParent(model);
if (!parent) return;
const index = parent.children.indexOf(model);
const id = rootComponent.doc.addBlock(
const id = host.doc.addBlock(
'affine:data-view',
{},
rootComponent.doc.getParent(model),
host.doc.getParent(model),
index + 1
);
const dataViewModel = rootComponent.doc.getBlock(id)!;
const dataViewModel = host.doc.getBlock(id)!;
Promise.resolve()
.then(() => {
const dataView = rootComponent.std.view.getBlock(
const dataView = std.view.getBlock(
dataViewModel.id
) as DataViewBlockComponent | null;
dataView?.dataSource.viewManager.viewAdd('table');
@@ -706,8 +705,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
showWhen: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:database') &&
!insideEdgelessText(model),
action: ({ rootComponent }) => {
rootComponent.std.command
action: ({ std }) => {
std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(insertDatabaseBlockCommand, {
@@ -717,8 +716,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
})
.pipe(({ insertedDatabaseBlockId }) => {
if (insertedDatabaseBlockId) {
const telemetry =
rootComponent.std.getOptional(TelemetryProvider);
const telemetry = std.getOptional(TelemetryProvider);
telemetry?.track('BlockCreated', {
blockType: 'affine:database',
});
@@ -735,15 +733,15 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
description: 'Shift this line up.',
icon: ArrowUpBigIcon,
tooltip: slashMenuToolTips['Move Up'],
action: ({ rootComponent, model }) => {
const doc = rootComponent.doc;
const previousSiblingModel = doc.getPrev(model);
action: ({ std, model }) => {
const { host } = std;
const previousSiblingModel = host.doc.getPrev(model);
if (!previousSiblingModel) return;
const parentModel = doc.getParent(previousSiblingModel);
const parentModel = host.doc.getParent(previousSiblingModel);
if (!parentModel) return;
doc.moveBlocks([model], parentModel, previousSiblingModel, true);
host.doc.moveBlocks([model], parentModel, previousSiblingModel, true);
},
},
{
@@ -751,15 +749,15 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
description: 'Shift this line down.',
icon: ArrowDownBigIcon,
tooltip: slashMenuToolTips['Move Down'],
action: ({ rootComponent, model }) => {
const doc = rootComponent.doc;
const nextSiblingModel = doc.getNext(model);
action: ({ std, model }) => {
const { host } = std;
const nextSiblingModel = host.doc.getNext(model);
if (!nextSiblingModel) return;
const parentModel = doc.getParent(nextSiblingModel);
const parentModel = host.doc.getParent(nextSiblingModel);
if (!parentModel) return;
doc.moveBlocks([model], parentModel, nextSiblingModel, false);
host.doc.moveBlocks([model], parentModel, nextSiblingModel, false);
},
},
{
@@ -767,13 +765,13 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
description: 'Copy this line to clipboard.',
icon: CopyIcon,
tooltip: slashMenuToolTips['Copy'],
action: ({ rootComponent, model }) => {
const slice = Slice.fromModels(rootComponent.std.store, [model]);
action: ({ std, model }) => {
const slice = Slice.fromModels(std.store, [model]);
rootComponent.std.clipboard
std.clipboard
.copy(slice)
.then(() => {
toast(rootComponent.host, 'Copied to clipboard');
toast(std.host, 'Copied to clipboard');
})
.catch(e => {
console.error(e);
@@ -785,12 +783,13 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
description: 'Create a duplicate of this line.',
icon: DualLinkIcon(),
tooltip: slashMenuToolTips['Copy'],
action: ({ rootComponent, model }) => {
action: ({ std, model }) => {
if (!model.text || !(model.text instanceof Text)) {
console.error("Can't duplicate a block without text");
return;
}
const parent = rootComponent.doc.getParent(model);
const { host } = std;
const parent = host.doc.getParent(model);
if (!parent) {
console.error(
'Failed to duplicate block! Parent not found: ' +
@@ -803,7 +802,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
const index = parent.children.indexOf(model);
// TODO add clone model util
rootComponent.doc.addBlock(
host.doc.addBlock(
model.flavour as never,
{
type: (model as ParagraphBlockModel).type,
@@ -811,7 +810,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
// @ts-expect-error FIXME: ts error
checked: model.checked,
},
rootComponent.doc.getParent(model),
host.doc.getParent(model),
index
);
},
@@ -822,8 +821,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
alias: ['remove'],
icon: DeleteIcon,
tooltip: slashMenuToolTips['Delete'],
action: ({ rootComponent, model }) => {
rootComponent.doc.deleteBlock(model);
action: ({ std, model }) => {
std.host.doc.deleteBlock(model);
},
},
],
@@ -0,0 +1,14 @@
import { InnerSlashMenu, SlashMenu } from './slash-menu-popover';
import { AFFINE_SLASH_MENU_WIDGET, AffineSlashMenuWidget } from './widget';
export function effects() {
customElements.define(AFFINE_SLASH_MENU_WIDGET, AffineSlashMenuWidget);
customElements.define('affine-slash-menu', SlashMenu);
customElements.define('inner-slash-menu', InnerSlashMenu);
}
declare global {
interface HTMLElementTagNameMap {
[AFFINE_SLASH_MENU_WIDGET]: AffineSlashMenuWidget;
}
}
@@ -0,0 +1,18 @@
import { WidgetViewExtension } from '@blocksuite/block-std';
import { type Container } from '@blocksuite/global/di';
import { Extension } from '@blocksuite/store';
import { literal, unsafeStatic } from 'lit/static-html.js';
import { AFFINE_SLASH_MENU_WIDGET } from './widget';
export class SlashMenuExtension extends Extension {
static override setup(di: Container) {
WidgetViewExtension(
'affine:page',
AFFINE_SLASH_MENU_WIDGET,
literal`${unsafeStatic(AFFINE_SLASH_MENU_WIDGET)}`
).setup(di);
di.add(this);
}
}
@@ -0,0 +1,3 @@
// TODO(@L-Sun): narrow the scope of the exported symbols
export * from './extensions';
export * from './widget';
@@ -9,6 +9,7 @@ import {
import {
createKeydownObserver,
getCurrentNativeRange,
getPopperPosition,
isControlledKeyboardEvent,
isFuzzyMatch,
substringMatchScore,
@@ -21,7 +22,6 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js';
import throttle from 'lodash-es/throttle';
import { getPopperPosition } from '../../utils/position.js';
import type {
SlashMenuActionItem,
SlashMenuContext,
@@ -147,7 +147,7 @@ export class SlashMenu extends WithDisposable(LitElement) {
}
get host() {
return this.context.rootComponent.host;
return this.context.std.host;
}
constructor(
@@ -480,7 +480,7 @@ export class InnerSlashMenu extends WithDisposable(LitElement) {
});
const inlineEditor = getInlineEditorByModel(
this.context.rootComponent.host,
this.context.std.host,
this.context.model
);
@@ -1,44 +1,44 @@
import type { TemplateResult } from 'lit';
import { AttachmentTooltip } from './attachment.js';
import { BoldTextTooltip } from './bold-text.js';
import { BulletedListTooltip } from './bulleted-list.js';
import { CodeBlockTooltip } from './code-block.js';
import { CopyTooltip } from './copy.js';
import { DeleteTooltip } from './delete.js';
import { DividerTooltip } from './divider.js';
import { EdgelessTooltip } from './edgeless.js';
import { FigmaTooltip } from './figma.js';
import { GithubRepoTooltip } from './github-repo.js';
import { Heading1Tooltip } from './heading-1.js';
import { Heading2Tooltip } from './heading-2.js';
import { Heading3Tooltip } from './heading-3.js';
import { Heading4Tooltip } from './heading-4.js';
import { Heading5Tooltip } from './heading-5.js';
import { Heading6Tooltip } from './heading-6.js';
import { ItalicTooltip } from './italic.js';
import { KanbanViewTooltip } from './kanban-view.js';
import { LinearTooltip } from './linear.js';
import { LinkTooltip } from './link.js';
import { LinkDocTooltip } from './link-doc.js';
import { MoveDownTooltip } from './move-down.js';
import { MoveUpTooltip } from './move-up.js';
import { NewDocTooltip } from './new-doc.js';
import { NowTooltip } from './now.js';
import { NumberedListTooltip } from './numbered-list.js';
import { PDFTooltip } from './pdf.js';
import { PhotoTooltip } from './photo.js';
import { QuoteTooltip } from './quote.js';
import { StrikethroughTooltip } from './strikethrough.js';
import { TableViewTooltip } from './table-view.js';
import { TextTooltip } from './text.js';
import { ToDoListTooltip } from './to-do-list.js';
import { TodayTooltip } from './today.js';
import { TomorrowTooltip } from './tomorrow.js';
import { TweetTooltip } from './tweet.js';
import { UnderlineTooltip } from './underline.js';
import { YesterdayTooltip } from './yesterday.js';
import { YoutubeVideoTooltip } from './youtube-video.js';
import { AttachmentTooltip } from './attachment';
import { BoldTextTooltip } from './bold-text';
import { BulletedListTooltip } from './bulleted-list';
import { CodeBlockTooltip } from './code-block';
import { CopyTooltip } from './copy';
import { DeleteTooltip } from './delete';
import { DividerTooltip } from './divider';
import { EdgelessTooltip } from './edgeless';
import { FigmaTooltip } from './figma';
import { GithubRepoTooltip } from './github-repo';
import { Heading1Tooltip } from './heading-1';
import { Heading2Tooltip } from './heading-2';
import { Heading3Tooltip } from './heading-3';
import { Heading4Tooltip } from './heading-4';
import { Heading5Tooltip } from './heading-5';
import { Heading6Tooltip } from './heading-6';
import { ItalicTooltip } from './italic';
import { KanbanViewTooltip } from './kanban-view';
import { LinearTooltip } from './linear';
import { LinkTooltip } from './link';
import { LinkDocTooltip } from './link-doc';
import { MoveDownTooltip } from './move-down';
import { MoveUpTooltip } from './move-up';
import { NewDocTooltip } from './new-doc';
import { NowTooltip } from './now';
import { NumberedListTooltip } from './numbered-list';
import { PDFTooltip } from './pdf';
import { PhotoTooltip } from './photo';
import { QuoteTooltip } from './quote';
import { StrikethroughTooltip } from './strikethrough';
import { TableViewTooltip } from './table-view';
import { TextTooltip } from './text';
import { ToDoListTooltip } from './to-do-list';
import { TodayTooltip } from './today';
import { TomorrowTooltip } from './tomorrow';
import { TweetTooltip } from './tweet';
import { UnderlineTooltip } from './underline';
import { YesterdayTooltip } from './yesterday';
import { YoutubeVideoTooltip } from './youtube-video';
export type SlashMenuTooltip = {
figure: TemplateResult;
@@ -103,8 +103,8 @@ export function createConversionItem(
icon,
tooltip: slashMenuToolTips[name],
showWhen: ({ model }) => model.doc.schema.flavourSchemaMap.has(flavour),
action: ({ rootComponent }) => {
rootComponent.std.command.exec(updateBlockType, {
action: ({ std }) => {
std.command.exec(updateBlockType, {
flavour,
props: { type },
});
@@ -120,8 +120,8 @@ export function createTextFormatItem(
name,
icon,
tooltip: slashMenuToolTips[name],
action: ({ rootComponent, model }) => {
const { std, host } = rootComponent;
action: ({ std, model }) => {
const { host } = std;
if (model.text?.length !== 0) {
std.command.exec(formatBlockCommand, {
@@ -139,3 +139,22 @@ export function createTextFormatItem(
},
};
}
export function formatDate(date: Date) {
// yyyy-mm-dd
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const strTime = `${year}-${month}-${day}`;
return strTime;
}
export function formatTime(date: Date) {
// mm-dd hh:mm
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const strTime = `${month}-${day} ${hours}:${minutes}`;
return strTime;
}
@@ -5,11 +5,9 @@ import {
import type { UIEventStateContext } from '@blocksuite/block-std';
import { TextSelection, WidgetComponent } from '@blocksuite/block-std';
import { DisposableGroup } from '@blocksuite/global/slot';
import { assertType } from '@blocksuite/global/utils';
import { InlineEditor } from '@blocksuite/inline';
import debounce from 'lodash-es/debounce';
import type { RootBlockComponent } from '../../types.js';
import {
defaultSlashMenuConfig,
type SlashMenuActionItem,
@@ -19,9 +17,9 @@ import {
type SlashMenuItemGenerator,
type SlashMenuStaticConfig,
type SlashSubMenu,
} from './config.js';
import { SlashMenu } from './slash-menu-popover.js';
import { filterEnabledSlashMenuItems } from './utils.js';
} from './config';
import { SlashMenu } from './slash-menu-popover';
import { filterEnabledSlashMenuItems } from './utils';
export type AffineSlashMenuContext = SlashMenuContext;
export type AffineSlashMenuItem = SlashMenuItem;
@@ -57,7 +55,7 @@ const showSlashMenu = debounce(
);
const inlineEditor = getInlineEditorByModel(
context.rootComponent.host,
context.std.host,
context.model
);
if (!inlineEditor) return;
@@ -115,12 +113,10 @@ export class AffineSlashMenuWidget extends WidgetComponent {
else inlineEditor.slots.inlineRangeSync.once(callback);
};
const rootComponent = this.block;
if (rootComponent.model.flavour !== 'affine:page') {
if (this.block.model.flavour !== 'affine:page') {
console.error('SlashMenuWidget should be used in RootBlock');
return;
}
assertType<RootBlockComponent>(rootComponent);
inlineRangeApplyCallback(() => {
const textSelection = this.host.selection.find(TextSelection);
@@ -155,7 +151,7 @@ export class AffineSlashMenuWidget extends WidgetComponent {
...this.config,
items: filterEnabledSlashMenuItems(this.config.items, {
model,
rootComponent,
std: this.std,
}),
};
@@ -163,7 +159,7 @@ export class AffineSlashMenuWidget extends WidgetComponent {
showSlashMenu({
context: {
model,
rootComponent,
std: this.std,
},
triggerKey: matchedKey,
config,
@@ -224,9 +220,3 @@ export class AffineSlashMenuWidget extends WidgetComponent {
this.handleEvent('compositionEnd', this._onCompositionEnd);
}
}
declare global {
interface HTMLElementTagNameMap {
[AFFINE_SLASH_MENU_WIDGET]: AffineSlashMenuWidget;
}
}
@@ -0,0 +1,27 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
},
"include": ["./src"],
"references": [
{ "path": "../block-attachment" },
{ "path": "../block-database" },
{ "path": "../block-embed" },
{ "path": "../block-image" },
{ "path": "../block-latex" },
{ "path": "../block-note" },
{ "path": "../block-surface" },
{ "path": "../block-surface-ref" },
{ "path": "../block-table" },
{ "path": "../components" },
{ "path": "../shared" },
{ "path": "../../framework/block-std" },
{ "path": "../data-view" },
{ "path": "../../framework/global" },
{ "path": "../../framework/inline" },
{ "path": "../../framework/store" }
]
}
+1
View File
@@ -43,6 +43,7 @@
"@blocksuite/affine-widget-frame-title": "workspace:*",
"@blocksuite/affine-widget-remote-selection": "workspace:*",
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*",
"@blocksuite/affine-widget-slash-menu": "workspace:*",
"@blocksuite/affine-widget-toolbar": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/data-view": "workspace:*",
+2
View File
@@ -46,6 +46,7 @@ import { effects as widgetEdgelessAutoConnectEffects } from '@blocksuite/affine-
import { effects as widgetFrameTitleEffects } from '@blocksuite/affine-widget-frame-title/effects';
import { effects as widgetRemoteSelectionEffects } from '@blocksuite/affine-widget-remote-selection/effects';
import { effects as widgetScrollAnchoringEffects } from '@blocksuite/affine-widget-scroll-anchoring/effects';
import { effects as widgetSlashMenuEffects } from '@blocksuite/affine-widget-slash-menu/effects';
import { effects as widgetToolbarEffects } from '@blocksuite/affine-widget-toolbar/effects';
import { effects as stdEffects } from '@blocksuite/block-std/effects';
import { effects as dataViewEffects } from '@blocksuite/data-view/effects';
@@ -103,6 +104,7 @@ export function effects() {
widgetRemoteSelectionEffects();
widgetDragHandleEffects();
widgetEdgelessAutoConnectEffects();
widgetSlashMenuEffects();
widgetToolbarEffects();
fragmentFramePanelEffects();
+3
View File
@@ -114,6 +114,9 @@ export {
export type { DragBlockPayload } from '@blocksuite/affine-widget-drag-handle';
export { toolbarWidget } from '@blocksuite/affine-widget-toolbar';
// TODO(@L-Sun): Narrow the export scope
export * from '@blocksuite/affine-widget-slash-menu';
const env: Record<string, unknown> =
typeof globalThis !== 'undefined'
? globalThis
+1
View File
@@ -36,6 +36,7 @@
{ "path": "../affine/widget-frame-title" },
{ "path": "../affine/widget-remote-selection" },
{ "path": "../affine/widget-scroll-anchoring" },
{ "path": "../affine/widget-slash-menu" },
{ "path": "../affine/widget-toolbar" },
{ "path": "../framework/block-std" },
{ "path": "../affine/data-view" },
@@ -29,26 +29,28 @@ export function setupSlashMenuAIEntry(slashMenu: AffineSlashMenuWidget) {
const showWhenWrapper =
(item?: AIItemConfig) =>
({ rootComponent }: AffineSlashMenuContext) => {
const affineAIPanelWidget = rootComponent.host.view.getWidget(
({ std }: AffineSlashMenuContext) => {
const root = std.host.doc.root;
if (!root) return false;
const affineAIPanelWidget = std.view.getWidget(
AFFINE_AI_PANEL_WIDGET,
rootComponent.model.id
root.id
);
if (affineAIPanelWidget === null) return false;
const chain = rootComponent.host.command.chain();
const docModeService = rootComponent.std.get(DocModeProvider);
const editorMode = docModeService.getPrimaryMode(rootComponent.doc.id);
const chain = std.host.command.chain();
const docModeService = std.get(DocModeProvider);
const editorMode = docModeService.getPrimaryMode(std.host.doc.id);
return item?.showWhen?.(chain, editorMode, rootComponent.host) ?? true;
return item?.showWhen?.(chain, editorMode, std.host) ?? true;
};
const actionItemWrapper = (
item: AIItemConfig
): AffineSlashMenuActionItem => ({
...basicItemConfig(item),
action: ({ rootComponent }: AffineSlashMenuContext) => {
item?.handler?.(rootComponent.host);
action: ({ std }: AffineSlashMenuContext) => {
item?.handler?.(std.host);
},
});
@@ -58,7 +60,7 @@ export function setupSlashMenuAIEntry(slashMenu: AffineSlashMenuWidget) {
subMenu: (item.subItem ?? []).map<AffineSlashMenuActionItem>(
({ type, handler }) => ({
name: type,
action: ({ rootComponent }) => handler?.(rootComponent.host),
action: ({ std }) => handler?.(std.host),
})
),
};
@@ -78,11 +80,12 @@ export function setupSlashMenuAIEntry(slashMenu: AffineSlashMenuWidget) {
name: 'Ask AI',
icon: AIStarIcon,
showWhen: showWhenWrapper(),
action: ({ rootComponent }) => {
const view = rootComponent.host.view;
const affineAIPanelWidget = view.getWidget(
action: ({ std }) => {
const root = std.host.doc.root;
if (!root) return;
const affineAIPanelWidget = std.view.getWidget(
AFFINE_AI_PANEL_WIDGET,
rootComponent.model.id
root.id
) as AffineAIPanelWidget;
handleInlineAskAIAction(affineAIPanelWidget.host);
},
@@ -17,7 +17,7 @@ import {
imageToolbarWidget,
ParagraphBlockService,
ReferenceNodeConfigIdentifier,
slashMenuWidget,
SlashMenuExtension,
surfaceRefToolbarWidget,
toolbarWidget,
VirtualKeyboardProvider as BSVirtualKeyboardProvider,
@@ -166,10 +166,10 @@ export function enableMobileExtension(
specBuilder: SpecBuilder,
framework: FrameworkProvider
): void {
specBuilder.omit(slashMenuWidget);
specBuilder.omit(codeToolbarWidget);
specBuilder.omit(imageToolbarWidget);
specBuilder.omit(surfaceRefToolbarWidget);
specBuilder.omit(toolbarWidget);
specBuilder.omit(SlashMenuExtension);
specBuilder.extend([MobileSpecsPatches, KeyboardToolbarExtension(framework)]);
}
@@ -137,11 +137,10 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
'action' in item &&
(item.name === 'Linked Doc' || item.name === 'Link')
) {
item.action = async ({ rootComponent }) => {
const [success, { insertedLinkType }] =
rootComponent.std.command.exec(
insertLinkByQuickSearchCommand
);
item.action = async ({ std }) => {
const [success, { insertedLinkType }] = std.command.exec(
insertLinkByQuickSearchCommand
);
if (!success) return;
+25
View File
@@ -250,6 +250,7 @@ export const PackageList = [
'blocksuite/affine/widget-frame-title',
'blocksuite/affine/widget-remote-selection',
'blocksuite/affine/widget-scroll-anchoring',
'blocksuite/affine/widget-slash-menu',
'blocksuite/affine/widget-toolbar',
'blocksuite/framework/block-std',
'blocksuite/affine/data-view',
@@ -435,6 +436,28 @@ export const PackageList = [
'blocksuite/framework/global',
],
},
{
location: 'blocksuite/affine/widget-slash-menu',
name: '@blocksuite/affine-widget-slash-menu',
workspaceDependencies: [
'blocksuite/affine/block-attachment',
'blocksuite/affine/block-database',
'blocksuite/affine/block-embed',
'blocksuite/affine/block-image',
'blocksuite/affine/block-latex',
'blocksuite/affine/block-note',
'blocksuite/affine/block-surface',
'blocksuite/affine/block-surface-ref',
'blocksuite/affine/block-table',
'blocksuite/affine/components',
'blocksuite/affine/shared',
'blocksuite/framework/block-std',
'blocksuite/affine/data-view',
'blocksuite/framework/global',
'blocksuite/framework/inline',
'blocksuite/framework/store',
],
},
{
location: 'blocksuite/affine/widget-toolbar',
name: '@blocksuite/affine-widget-toolbar',
@@ -481,6 +504,7 @@ export const PackageList = [
'blocksuite/affine/widget-frame-title',
'blocksuite/affine/widget-remote-selection',
'blocksuite/affine/widget-scroll-anchoring',
'blocksuite/affine/widget-slash-menu',
'blocksuite/affine/widget-toolbar',
'blocksuite/framework/block-std',
'blocksuite/affine/data-view',
@@ -887,6 +911,7 @@ export type PackageName =
| '@blocksuite/affine-widget-frame-title'
| '@blocksuite/affine-widget-remote-selection'
| '@blocksuite/affine-widget-scroll-anchoring'
| '@blocksuite/affine-widget-slash-menu'
| '@blocksuite/affine-widget-toolbar'
| '@blocksuite/blocks'
| '@blocksuite/block-std'
+1
View File
@@ -81,6 +81,7 @@
{ "path": "./blocksuite/affine/widget-frame-title" },
{ "path": "./blocksuite/affine/widget-remote-selection" },
{ "path": "./blocksuite/affine/widget-scroll-anchoring" },
{ "path": "./blocksuite/affine/widget-slash-menu" },
{ "path": "./blocksuite/affine/widget-toolbar" },
{ "path": "./blocksuite/blocks" },
{ "path": "./blocksuite/framework/block-std" },
+33 -1
View File
@@ -2608,6 +2608,7 @@ __metadata:
"@blocksuite/affine-widget-frame-title": "workspace:*"
"@blocksuite/affine-widget-remote-selection": "workspace:*"
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*"
"@blocksuite/affine-widget-slash-menu": "workspace:*"
"@blocksuite/affine-widget-toolbar": "workspace:*"
"@blocksuite/block-std": "workspace:*"
"@blocksuite/data-view": "workspace:*"
@@ -2948,6 +2949,36 @@ __metadata:
languageName: unknown
linkType: soft
"@blocksuite/affine-widget-slash-menu@workspace:*, @blocksuite/affine-widget-slash-menu@workspace:blocksuite/affine/widget-slash-menu":
version: 0.0.0-use.local
resolution: "@blocksuite/affine-widget-slash-menu@workspace:blocksuite/affine/widget-slash-menu"
dependencies:
"@blocksuite/affine-block-attachment": "workspace:*"
"@blocksuite/affine-block-database": "workspace:*"
"@blocksuite/affine-block-embed": "workspace:*"
"@blocksuite/affine-block-image": "workspace:*"
"@blocksuite/affine-block-latex": "workspace:*"
"@blocksuite/affine-block-note": "workspace:*"
"@blocksuite/affine-block-surface": "workspace:*"
"@blocksuite/affine-block-surface-ref": "workspace:*"
"@blocksuite/affine-block-table": "workspace:*"
"@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-shared": "workspace:*"
"@blocksuite/block-std": "workspace:*"
"@blocksuite/data-view": "workspace:*"
"@blocksuite/global": "workspace:*"
"@blocksuite/icons": "npm:^2.2.4"
"@blocksuite/inline": "workspace:*"
"@blocksuite/store": "workspace:*"
"@floating-ui/dom": "npm:^1.6.13"
"@preact/signals-core": "npm:^1.8.0"
"@toeverything/theme": "npm:^1.1.12"
"@types/lodash-es": "npm:^4.17.12"
lit: "npm:^3.2.0"
lodash-es: "npm:^4.17.21"
languageName: unknown
linkType: soft
"@blocksuite/affine-widget-toolbar@workspace:*, @blocksuite/affine-widget-toolbar@workspace:blocksuite/affine/widget-toolbar":
version: 0.0.0-use.local
resolution: "@blocksuite/affine-widget-toolbar@workspace:blocksuite/affine/widget-toolbar"
@@ -3049,6 +3080,7 @@ __metadata:
"@blocksuite/affine-widget-frame-title": "workspace:*"
"@blocksuite/affine-widget-remote-selection": "workspace:*"
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*"
"@blocksuite/affine-widget-slash-menu": "workspace:*"
"@blocksuite/affine-widget-toolbar": "workspace:*"
"@blocksuite/block-std": "workspace:*"
"@blocksuite/data-view": "workspace:*"
@@ -3097,7 +3129,7 @@ __metadata:
languageName: unknown
linkType: soft
"@blocksuite/icons@npm:2.2.4, @blocksuite/icons@npm:^2.2.1, @blocksuite/icons@npm:^2.2.2, @blocksuite/icons@npm:^2.2.3":
"@blocksuite/icons@npm:2.2.4, @blocksuite/icons@npm:^2.2.1, @blocksuite/icons@npm:^2.2.2, @blocksuite/icons@npm:^2.2.3, @blocksuite/icons@npm:^2.2.4":
version: 2.2.4
resolution: "@blocksuite/icons@npm:2.2.4"
peerDependencies: