mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 02:35:58 +08:00
refactor(editor): linked doc slash menu config extension (#10682)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import { EmbedLinkedDocBlockSchema } from '@blocksuite/affine-model';
|
||||
import {
|
||||
getInlineEditorByModel,
|
||||
insertContent,
|
||||
} from '@blocksuite/affine-rich-text';
|
||||
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
||||
import { createDefaultDoc } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
type SlashMenuConfig,
|
||||
SlashMenuConfigIdentifier,
|
||||
} from '@blocksuite/affine-widget-slash-menu';
|
||||
import { LinkedPageIcon, PlusIcon } from '@blocksuite/icons/lit';
|
||||
import { type ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import { LinkDocTooltip, NewDocTooltip } from './tooltips';
|
||||
|
||||
const linkedDocSlashMenuConfig: SlashMenuConfig = {
|
||||
items: [
|
||||
{
|
||||
name: 'New Doc',
|
||||
description: 'Start a new document.',
|
||||
icon: PlusIcon(),
|
||||
tooltip: {
|
||||
figure: NewDocTooltip,
|
||||
caption: 'New Doc',
|
||||
},
|
||||
group: '3_Page@0',
|
||||
when: ({ model }) =>
|
||||
model.doc.schema.flavourSchemaMap.has('affine:embed-linked-doc'),
|
||||
action: ({ std, model }) => {
|
||||
const newDoc = createDefaultDoc(std.host.doc.workspace);
|
||||
insertContent(std.host, model, REFERENCE_NODE, {
|
||||
reference: {
|
||||
type: 'LinkedPage',
|
||||
pageId: newDoc.id,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Linked Doc',
|
||||
description: 'Link to another document.',
|
||||
icon: LinkedPageIcon(),
|
||||
tooltip: {
|
||||
figure: LinkDocTooltip,
|
||||
caption: 'Link Doc',
|
||||
},
|
||||
searchAlias: ['dual link'],
|
||||
group: '3_Page@1',
|
||||
when: ({ std, model }) => {
|
||||
const root = model.doc.root;
|
||||
if (!root) return false;
|
||||
const linkedDocWidget = std.view.getWidget(
|
||||
'affine-linked-doc-widget',
|
||||
root.id
|
||||
);
|
||||
if (!linkedDocWidget) return false;
|
||||
|
||||
return model.doc.schema.flavourSchemaMap.has('affine:embed-linked-doc');
|
||||
},
|
||||
action: ({ model, std }) => {
|
||||
const root = model.doc.root;
|
||||
if (!root) return;
|
||||
const linkedDocWidget = std.view.getWidget(
|
||||
'affine-linked-doc-widget',
|
||||
root.id
|
||||
);
|
||||
if (!linkedDocWidget) return;
|
||||
// TODO(@L-Sun): make linked-doc-widget as extension
|
||||
// @ts-expect-error same as above
|
||||
const triggerKey = linkedDocWidget.config.triggerKeys[0];
|
||||
|
||||
insertContent(std.host, model, triggerKey);
|
||||
|
||||
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 });
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const LinkedDocSlashMenuConfigIdentifier = SlashMenuConfigIdentifier(
|
||||
EmbedLinkedDocBlockSchema.model.flavour
|
||||
);
|
||||
|
||||
export const LinkedDocSlashMenuConfigExtension: ExtensionType = {
|
||||
setup: di => {
|
||||
di.addImpl(LinkedDocSlashMenuConfigIdentifier, linkedDocSlashMenuConfig);
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
import { html } from 'lit';
|
||||
// prettier-ignore
|
||||
export const NewDocTooltip = html`<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="170" height="68" rx="2" fill="white"/>
|
||||
<mask id="mask0_16460_991" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
||||
<rect width="170" height="68" rx="2" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_16460_991)">
|
||||
<text fill="#8E8D91" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="22" font-weight="600" letter-spacing="0px"><tspan x="8" y="27.5">Title</tspan></text>
|
||||
<text fill="#8E8D91" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="8" y="44.6364">Type '/' for commands</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
// prettier-ignore
|
||||
export const LinkDocTooltip = html`<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="170" height="68" rx="2" fill="white"/>
|
||||
<mask id="mask0_16460_998" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
||||
<rect width="170" height="68" rx="2" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_16460_998)">
|
||||
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="8" y="15.6364">In a decentralized system, we can have a kaleidoscopic </tspan><tspan x="8" y="27.6364">complexity to our data. </tspan><tspan x="8" y="63.6364">Any user may have a different perspective on what data they </tspan><tspan x="8" y="75.6364">either have, choose to share, or accept. </tspan><tspan x="8" y="111.636">For example, one user’s edits to a document might be on </tspan><tspan x="8" y="123.636">their laptop on an airplane; when the plane lands and the </tspan><tspan x="8" y="135.636">computer reconnects, those changes are distributed to </tspan><tspan x="8" y="147.636">other users. </tspan><tspan x="8" y="183.636">Other users might choose to accept all, some, or none of </tspan><tspan x="8" y="195.636">those changes to their version of the document.</tspan></text>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.125 39C10.125 38.2406 10.7406 37.625 11.5 37.625H16.5C17.2594 37.625 17.875 38.2406 17.875 39V42C17.875 42.2071 17.7071 42.375 17.5 42.375C17.2929 42.375 17.125 42.2071 17.125 42V39C17.125 38.6548 16.8452 38.375 16.5 38.375H11.5C11.1548 38.375 10.875 38.6548 10.875 39V45C10.875 45.3452 11.1548 45.625 11.5 45.625H14C14.2071 45.625 14.375 45.7929 14.375 46C14.375 46.2071 14.2071 46.375 14 46.375H11.5C10.7406 46.375 10.125 45.7594 10.125 45V39ZM12.125 40C12.125 39.7929 12.2929 39.625 12.5 39.625H14C14.2071 39.625 14.375 39.7929 14.375 40C14.375 40.2071 14.2071 40.375 14 40.375H12.5C12.2929 40.375 12.125 40.2071 12.125 40ZM12.5 41.375C12.2929 41.375 12.125 41.5429 12.125 41.75C12.125 41.9571 12.2929 42.125 12.5 42.125H15.5C15.7071 42.125 15.875 41.9571 15.875 41.75C15.875 41.5429 15.7071 41.375 15.5 41.375H12.5ZM12.125 43.5C12.125 43.2929 12.2929 43.125 12.5 43.125H13.75C13.9571 43.125 14.125 43.2929 14.125 43.5C14.125 43.7071 13.9571 43.875 13.75 43.875H12.5C12.2929 43.875 12.125 43.7071 12.125 43.5ZM15.75 43.125C15.5429 43.125 15.375 43.2929 15.375 43.5C15.375 43.7071 15.5429 43.875 15.75 43.875H17.0947L15.2348 45.7348C15.0884 45.8813 15.0884 46.1187 15.2348 46.2652C15.3813 46.4116 15.6187 46.4116 15.7652 46.2652L17.625 44.4053V45.75C17.625 45.9571 17.7929 46.125 18 46.125C18.2071 46.125 18.375 45.9571 18.375 45.75V43.5C18.375 43.4005 18.3355 43.3052 18.2652 43.2348C18.1948 43.1645 18.0995 43.125 18 43.125H15.75Z" fill="#77757D"/>
|
||||
<mask id="path-5-inside-1_16460_998" fill="white">
|
||||
<path d="M24 35H98V49H24V35Z"/>
|
||||
</mask>
|
||||
<path d="M98 48.5H24V49.5H98V48.5Z" fill="#E3E2E4" mask="url(#path-5-inside-1_16460_998)"/>
|
||||
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="24" y="45.6364">What’s AFFiNE?</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
@@ -8,6 +8,7 @@ import type { ExtensionType } from '@blocksuite/store';
|
||||
import { literal } from 'lit/static-html.js';
|
||||
|
||||
import { EmbedLinkedDocBlockAdapterExtensions } from './adapters/extension';
|
||||
import { LinkedDocSlashMenuConfigExtension } from './configs/slash-menu';
|
||||
import { builtinToolbarConfig } from './configs/toolbar';
|
||||
|
||||
const flavour = EmbedLinkedDocBlockSchema.model.flavour;
|
||||
@@ -23,4 +24,5 @@ export const EmbedLinkedDocBlockSpec: ExtensionType[] = [
|
||||
id: BlockServiceIdentifier(flavour),
|
||||
config: builtinToolbarConfig,
|
||||
}),
|
||||
LinkedDocSlashMenuConfigExtension,
|
||||
].flat();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './adapters';
|
||||
export * from './commands';
|
||||
export { LinkedDocSlashMenuConfigIdentifier } from './configs/slash-menu';
|
||||
export * from './embed-linked-doc-block';
|
||||
export * from './embed-linked-doc-spec';
|
||||
|
||||
Reference in New Issue
Block a user