feat: add outline plugin (#3624)
Co-authored-by: codert <codert.sn@gmail.com>
This commit is contained in:
@@ -36,9 +36,13 @@ const importLogger = new DebugLogger('plugins:import');
|
|||||||
const pushLayoutAtom = atom<
|
const pushLayoutAtom = atom<
|
||||||
null,
|
null,
|
||||||
// fixme: check plugin name here
|
// fixme: check plugin name here
|
||||||
[pluginName: string, create: (root: HTMLElement) => () => void],
|
[
|
||||||
|
pluginName: string,
|
||||||
|
create: (root: HTMLElement) => () => void,
|
||||||
|
options: { maxWidth: (number | undefined)[] } | undefined,
|
||||||
|
],
|
||||||
void
|
void
|
||||||
>(null, (_, set, pluginName, callback) => {
|
>(null, (_, set, pluginName, callback, options) => {
|
||||||
set(pluginWindowAtom, items => ({
|
set(pluginWindowAtom, items => ({
|
||||||
...items,
|
...items,
|
||||||
[pluginName]: callback,
|
[pluginName]: callback,
|
||||||
@@ -50,20 +54,20 @@ const pushLayoutAtom = atom<
|
|||||||
first: 'editor',
|
first: 'editor',
|
||||||
second: pluginName,
|
second: pluginName,
|
||||||
splitPercentage: 70,
|
splitPercentage: 70,
|
||||||
|
maxWidth: options?.maxWidth,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
...layout,
|
|
||||||
direction: 'horizontal',
|
direction: 'horizontal',
|
||||||
first: 'editor',
|
first: 'editor',
|
||||||
|
splitPercentage: 70,
|
||||||
second: {
|
second: {
|
||||||
direction: 'horizontal',
|
direction: 'horizontal',
|
||||||
// fixme: incorrect type here
|
first: pluginName,
|
||||||
first: layout.second,
|
second: layout.second,
|
||||||
second: pluginName,
|
splitPercentage: 50,
|
||||||
splitPercentage: 70,
|
|
||||||
},
|
},
|
||||||
} as ExpectedLayout;
|
} satisfies ExpectedLayout;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addCleanup(pluginName, () => {
|
addCleanup(pluginName, () => {
|
||||||
@@ -77,36 +81,27 @@ const deleteLayoutAtom = atom<null, [string], void>(null, (_, set, id) => {
|
|||||||
delete newItems[id];
|
delete newItems[id];
|
||||||
return newItems;
|
return newItems;
|
||||||
});
|
});
|
||||||
const removeLayout = (layout: LayoutNode): LayoutNode => {
|
const removeLayout = (layout: LayoutNode): LayoutNode | string => {
|
||||||
if (layout === 'editor') {
|
if (typeof layout === 'string') {
|
||||||
return 'editor';
|
return layout;
|
||||||
|
}
|
||||||
|
if (layout.first === id) {
|
||||||
|
return layout.second;
|
||||||
|
} else if (layout.second === id) {
|
||||||
|
return layout.first;
|
||||||
} else {
|
} else {
|
||||||
if (typeof layout === 'string') {
|
return {
|
||||||
return layout as ExpectedLayout;
|
...layout,
|
||||||
}
|
second: removeLayout(layout.second),
|
||||||
if (layout.first === id) {
|
};
|
||||||
return layout.second;
|
|
||||||
} else if (layout.second === id) {
|
|
||||||
return layout.first;
|
|
||||||
} else {
|
|
||||||
return removeLayout(layout.second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
set(contentLayoutAtom, layout => {
|
set(contentLayoutAtom, layout => {
|
||||||
if (layout === 'editor') {
|
if (layout === 'editor') {
|
||||||
return 'editor';
|
return 'editor';
|
||||||
} else {
|
} else {
|
||||||
if (typeof layout === 'string') {
|
return removeLayout(layout) as ExpectedLayout;
|
||||||
return layout as ExpectedLayout;
|
|
||||||
}
|
|
||||||
if (layout.first === id) {
|
|
||||||
return layout.second as ExpectedLayout;
|
|
||||||
} else if (layout.second === id) {
|
|
||||||
return layout.first as ExpectedLayout;
|
|
||||||
} else {
|
|
||||||
return removeLayout(layout.second) as ExpectedLayout;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -123,6 +118,7 @@ const rootImportsMapSetupPromise = setupImportsMap(_rootImportsMap, {
|
|||||||
swr: import('swr'),
|
swr: import('swr'),
|
||||||
'@affine/component': import('@affine/component'),
|
'@affine/component': import('@affine/component'),
|
||||||
'@blocksuite/icons': import('@blocksuite/icons'),
|
'@blocksuite/icons': import('@blocksuite/icons'),
|
||||||
|
'@blocksuite/blocks': import('@blocksuite/blocks'),
|
||||||
'@affine/sdk/entry': {
|
'@affine/sdk/entry': {
|
||||||
rootStore: rootStore,
|
rootStore: rootStore,
|
||||||
currentWorkspaceAtom: currentWorkspaceAtom,
|
currentWorkspaceAtom: currentWorkspaceAtom,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { contentLayoutAtom, rootStore } from '@toeverything/infra/atom';
|
|||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
import { useAtomValue, useSetAtom } from 'jotai';
|
||||||
import type { CSSProperties, ReactElement } from 'react';
|
import type { CSSProperties, ReactElement } from 'react';
|
||||||
import { memo, Suspense, useCallback, useMemo } from 'react';
|
import { memo, startTransition, Suspense, useCallback, useMemo } from 'react';
|
||||||
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
||||||
|
|
||||||
import { pageSettingFamily } from '../atoms';
|
import { pageSettingFamily } from '../atoms';
|
||||||
@@ -140,12 +140,14 @@ const PluginContentAdapter = memo<PluginContentAdapterProps>(
|
|||||||
ref={useCallback(
|
ref={useCallback(
|
||||||
(ref: HTMLDivElement | null) => {
|
(ref: HTMLDivElement | null) => {
|
||||||
if (ref) {
|
if (ref) {
|
||||||
const div = document.createElement('div');
|
startTransition(() => {
|
||||||
const cleanup = windowItem(div);
|
const div = document.createElement('div');
|
||||||
ref.appendChild(div);
|
const cleanup = windowItem(div);
|
||||||
addCleanup(pluginName, () => {
|
ref.appendChild(div);
|
||||||
cleanup();
|
addCleanup(pluginName, () => {
|
||||||
ref.removeChild(div);
|
cleanup();
|
||||||
|
ref.removeChild(div);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -181,7 +183,12 @@ const LayoutPanel = memo(function LayoutPanel(
|
|||||||
}}
|
}}
|
||||||
direction={node.direction}
|
direction={node.direction}
|
||||||
>
|
>
|
||||||
<Panel defaultSize={node.splitPercentage}>
|
<Panel
|
||||||
|
defaultSize={node.splitPercentage}
|
||||||
|
style={{
|
||||||
|
maxWidth: node.maxWidth?.[0],
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<LayoutPanel node={node.first} editorProps={props.editorProps} />
|
<LayoutPanel node={node.first} editorProps={props.editorProps} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
@@ -191,6 +198,7 @@ const LayoutPanel = memo(function LayoutPanel(
|
|||||||
defaultSize={100 - node.splitPercentage}
|
defaultSize={100 - node.splitPercentage}
|
||||||
style={{
|
style={{
|
||||||
overflow: 'scroll',
|
overflow: 'scroll',
|
||||||
|
maxWidth: node.maxWidth?.[1],
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export const builtinPluginPaths = new Set([
|
|||||||
'/plugins/hello-world',
|
'/plugins/hello-world',
|
||||||
'/plugins/image-preview',
|
'/plugins/image-preview',
|
||||||
'/plugins/vue-hello-world',
|
'/plugins/vue-hello-world',
|
||||||
|
'/plugins/outline',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const pluginCleanupMap = new Map<string, (() => void)[]>();
|
const pluginCleanupMap = new Map<string, (() => void)[]>();
|
||||||
@@ -34,6 +35,7 @@ export const pluginPackageJson = atom<
|
|||||||
export const enabledPluginAtom = atomWithStorage('affine-enabled-plugin', [
|
export const enabledPluginAtom = atomWithStorage('affine-enabled-plugin', [
|
||||||
'@affine/bookmark-plugin',
|
'@affine/bookmark-plugin',
|
||||||
'@affine/image-preview-plugin',
|
'@affine/image-preview-plugin',
|
||||||
|
'@affine/outline-plugin',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const pluginHeaderItemAtom = atom<
|
export const pluginHeaderItemAtom = atom<
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export type LayoutParentNode = {
|
|||||||
splitPercentage: number; // 0 - 100
|
splitPercentage: number; // 0 - 100
|
||||||
first: string;
|
first: string;
|
||||||
second: LayoutNode;
|
second: LayoutNode;
|
||||||
|
maxWidth?: (number | undefined)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ExpectedLayout =
|
export type ExpectedLayout =
|
||||||
@@ -48,7 +49,14 @@ export type ExpectedLayout =
|
|||||||
|
|
||||||
export declare const pushLayoutAtom: WritableAtom<
|
export declare const pushLayoutAtom: WritableAtom<
|
||||||
null,
|
null,
|
||||||
[string, (div: HTMLDivElement) => () => void],
|
| [
|
||||||
|
string,
|
||||||
|
(div: HTMLDivElement) => () => void,
|
||||||
|
{
|
||||||
|
maxWidth: (number | undefined)[];
|
||||||
|
},
|
||||||
|
]
|
||||||
|
| [string, (div: HTMLDivElement) => () => void],
|
||||||
void
|
void
|
||||||
>;
|
>;
|
||||||
export declare const deleteLayoutAtom: WritableAtom<null, [string], void>;
|
export declare const deleteLayoutAtom: WritableAtom<null, [string], void>;
|
||||||
|
|||||||
29
plugins/outline/package.json
Normal file
29
plugins/outline/package.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "@affine/outline-plugin",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"description": "Outline plugin",
|
||||||
|
"version": "0.8.0-canary.13",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "af dev",
|
||||||
|
"build": "af build"
|
||||||
|
},
|
||||||
|
"affinePlugin": {
|
||||||
|
"release": "development",
|
||||||
|
"entry": {
|
||||||
|
"core": "./src/index.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@affine/component": "workspace:*",
|
||||||
|
"@affine/sdk": "workspace:*",
|
||||||
|
"@blocksuite/icons": "^2.1.29",
|
||||||
|
"@toeverything/components": "^0.0.8"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@affine/plugin-cli": "workspace:*",
|
||||||
|
"jotai": "^2.2.2",
|
||||||
|
"react": "18.2.0",
|
||||||
|
"react-dom": "18.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
plugins/outline/project.json
Normal file
26
plugins/outline/project.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "@affine/outline-plugin",
|
||||||
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"namedInputs": {
|
||||||
|
"default": [
|
||||||
|
"{projectRoot}/**/*",
|
||||||
|
"{workspaceRoot}/packages/plugin-cli/src/**/*",
|
||||||
|
"sharedGlobals"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"targets": {
|
||||||
|
"build": {
|
||||||
|
"executor": "nx:run-script",
|
||||||
|
"options": {
|
||||||
|
"script": "build"
|
||||||
|
},
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"inputs": ["default"],
|
||||||
|
"outputs": [
|
||||||
|
"{workspaceRoot}/apps/core/public/plugins/outline",
|
||||||
|
"{workspaceRoot}/apps/electron/dist/plugins/outline"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": ["plugin"]
|
||||||
|
}
|
||||||
96
plugins/outline/src/app.tsx
Normal file
96
plugins/outline/src/app.tsx
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { Tooltip } from '@affine/component';
|
||||||
|
import { deleteLayoutAtom, pushLayoutAtom } from '@affine/sdk/entry';
|
||||||
|
import { TOCNotesPanel } from '@blocksuite/blocks';
|
||||||
|
import { RightSidebarIcon } from '@blocksuite/icons';
|
||||||
|
import type { Page } from '@blocksuite/store';
|
||||||
|
import { IconButton } from '@toeverything/components/button';
|
||||||
|
import { useAtom, useSetAtom } from 'jotai';
|
||||||
|
import type { ComponentType, PropsWithChildren } from 'react';
|
||||||
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
|
import { blocksuiteRootAtom } from './atom';
|
||||||
|
|
||||||
|
const Outline = () => {
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const tocPanelRef = useRef<TOCNotesPanel | null>(null);
|
||||||
|
const [blocksuite] = useAtom(blocksuiteRootAtom);
|
||||||
|
|
||||||
|
if (!tocPanelRef.current) {
|
||||||
|
tocPanelRef.current = new TOCNotesPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blocksuite?.page !== tocPanelRef.current?.page) {
|
||||||
|
(tocPanelRef.current as TOCNotesPanel).page = blocksuite?.page as Page;
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ref.current || !tocPanelRef.current) return;
|
||||||
|
|
||||||
|
const container = ref.current;
|
||||||
|
const tocPanel = tocPanelRef.current as TOCNotesPanel;
|
||||||
|
|
||||||
|
container.appendChild(tocPanel);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
container.removeChild(tocPanel);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`outline-wrapper`}
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
borderLeft: `1px solid var(--affine-border-color)`,
|
||||||
|
}}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const HeaderItem = ({
|
||||||
|
Provider,
|
||||||
|
}: {
|
||||||
|
Provider: ComponentType<PropsWithChildren>;
|
||||||
|
}) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const pushLayout = useSetAtom(pushLayoutAtom);
|
||||||
|
const deleteLayout = useSetAtom(deleteLayoutAtom);
|
||||||
|
return (
|
||||||
|
<Tooltip content="Plugin Enabled">
|
||||||
|
<IconButton
|
||||||
|
onClick={useCallback(() => {
|
||||||
|
if (!open) {
|
||||||
|
setOpen(true);
|
||||||
|
pushLayout(
|
||||||
|
'@affine/outline-plugin',
|
||||||
|
div => {
|
||||||
|
const root = createRoot(div);
|
||||||
|
|
||||||
|
div.style.height = '100%';
|
||||||
|
|
||||||
|
root.render(
|
||||||
|
<Provider>
|
||||||
|
<Outline />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
return () => {
|
||||||
|
root.unmount();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
maxWidth: [undefined, 300],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setOpen(false);
|
||||||
|
deleteLayout('@affine/outline-plugin');
|
||||||
|
}
|
||||||
|
}, [Provider, deleteLayout, open, pushLayout])}
|
||||||
|
>
|
||||||
|
<RightSidebarIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
5
plugins/outline/src/atom.ts
Normal file
5
plugins/outline/src/atom.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { atom } from 'jotai';
|
||||||
|
|
||||||
|
export const blocksuiteRootAtom = atom(() =>
|
||||||
|
document.querySelector('block-suite-root')
|
||||||
|
);
|
||||||
41
plugins/outline/src/index.ts
Normal file
41
plugins/outline/src/index.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import type { PluginContext } from '@affine/sdk/entry';
|
||||||
|
import { registerTOCComponents } from '@blocksuite/blocks';
|
||||||
|
import { createElement } from 'react';
|
||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
|
import { HeaderItem } from './app';
|
||||||
|
|
||||||
|
export const entry = (context: PluginContext) => {
|
||||||
|
console.log('register outline');
|
||||||
|
|
||||||
|
context.register('headerItem', div => {
|
||||||
|
registerTOCComponents(components => {
|
||||||
|
for (const compName in components) {
|
||||||
|
if (window.customElements.get(compName)) continue;
|
||||||
|
|
||||||
|
window.customElements.define(
|
||||||
|
compName,
|
||||||
|
components[compName as keyof typeof components]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
div.style.height = '100%';
|
||||||
|
|
||||||
|
const root = createRoot(div);
|
||||||
|
root.render(
|
||||||
|
createElement(
|
||||||
|
context.utils.PluginProvider,
|
||||||
|
{},
|
||||||
|
createElement(HeaderItem, {
|
||||||
|
Provider: context.utils.PluginProvider,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return () => {
|
||||||
|
root.unmount();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
};
|
||||||
17
plugins/outline/tsconfig.json
Normal file
17
plugins/outline/tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"include": ["./src"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": false,
|
||||||
|
"outDir": "lib",
|
||||||
|
"jsx": "preserve"
|
||||||
|
},
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../../packages/sdk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/component"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -19,36 +19,20 @@ test('plugin should exist', async ({ page }) => {
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
return window.__pluginPackageJson__;
|
return window.__pluginPackageJson__;
|
||||||
});
|
});
|
||||||
expect(packageJson).toEqual([
|
const plugins = [
|
||||||
{
|
'@affine/bookmark-plugin',
|
||||||
name: '@affine/bookmark-plugin',
|
'@affine/copilot-plugin',
|
||||||
|
'@affine/hello-world-plugin',
|
||||||
|
'@affine/image-preview-plugin',
|
||||||
|
'@affine/vue-hello-world-plugin',
|
||||||
|
'@affine/outline-plugin',
|
||||||
|
];
|
||||||
|
expect(packageJson).toEqual(
|
||||||
|
plugins.map(name => ({
|
||||||
|
name,
|
||||||
version: expect.any(String),
|
version: expect.any(String),
|
||||||
description: expect.any(String),
|
description: expect.any(String),
|
||||||
affinePlugin: expect.anything(),
|
affinePlugin: expect.anything(),
|
||||||
},
|
}))
|
||||||
{
|
);
|
||||||
name: '@affine/copilot-plugin',
|
|
||||||
version: expect.any(String),
|
|
||||||
description: expect.any(String),
|
|
||||||
affinePlugin: expect.anything(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@affine/hello-world-plugin',
|
|
||||||
version: expect.any(String),
|
|
||||||
description: expect.any(String),
|
|
||||||
affinePlugin: expect.anything(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@affine/image-preview-plugin',
|
|
||||||
version: expect.any(String),
|
|
||||||
description: expect.any(String),
|
|
||||||
affinePlugin: expect.anything(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@affine/vue-hello-world-plugin',
|
|
||||||
version: expect.any(String),
|
|
||||||
description: expect.any(String),
|
|
||||||
affinePlugin: expect.anything(),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|||||||
33
yarn.lock
33
yarn.lock
@@ -554,6 +554,21 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"@affine/outline-plugin@workspace:plugins/outline":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@affine/outline-plugin@workspace:plugins/outline"
|
||||||
|
dependencies:
|
||||||
|
"@affine/component": "workspace:*"
|
||||||
|
"@affine/plugin-cli": "workspace:*"
|
||||||
|
"@affine/sdk": "workspace:*"
|
||||||
|
"@blocksuite/icons": ^2.1.29
|
||||||
|
"@toeverything/components": ^0.0.8
|
||||||
|
jotai: ^2.2.2
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@affine/plugin-cli@workspace:*, @affine/plugin-cli@workspace:packages/plugin-cli":
|
"@affine/plugin-cli@workspace:*, @affine/plugin-cli@workspace:packages/plugin-cli":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@affine/plugin-cli@workspace:packages/plugin-cli"
|
resolution: "@affine/plugin-cli@workspace:packages/plugin-cli"
|
||||||
@@ -3441,7 +3456,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/icons@npm:^2.1.30, @blocksuite/icons@npm:^2.1.31":
|
"@blocksuite/icons@npm:^2.1.26, @blocksuite/icons@npm:^2.1.29, @blocksuite/icons@npm:^2.1.30, @blocksuite/icons@npm:^2.1.31":
|
||||||
version: 2.1.31
|
version: 2.1.31
|
||||||
resolution: "@blocksuite/icons@npm:2.1.31"
|
resolution: "@blocksuite/icons@npm:2.1.31"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -11424,6 +11439,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@toeverything/components@npm:^0.0.8":
|
||||||
|
version: 0.0.8
|
||||||
|
resolution: "@toeverything/components@npm:0.0.8"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/icons": ^2.1.26
|
||||||
|
peerDependencies:
|
||||||
|
"@radix-ui/react-avatar": ^1
|
||||||
|
clsx: ^2
|
||||||
|
react: ^18
|
||||||
|
react-dom: ^18
|
||||||
|
checksum: 9c955d3c46729397e92031cc6a5ba0f15eb8a67893862b4c6c017c87fff2ab8e9ee8505695b0da571f2af35ad6545f643fc34f657f1c9d1913648796971540d9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@toeverything/hooks@workspace:*, @toeverything/hooks@workspace:packages/hooks":
|
"@toeverything/hooks@workspace:*, @toeverything/hooks@workspace:packages/hooks":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@toeverything/hooks@workspace:packages/hooks"
|
resolution: "@toeverything/hooks@workspace:packages/hooks"
|
||||||
@@ -22753,7 +22782,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"jotai@npm:^2.3.1":
|
"jotai@npm:^2.2.2, jotai@npm:^2.3.1":
|
||||||
version: 2.3.1
|
version: 2.3.1
|
||||||
resolution: "jotai@npm:2.3.1"
|
resolution: "jotai@npm:2.3.1"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user