diff --git a/packages/frontend/apps/electron/renderer/app.tsx b/packages/frontend/apps/electron/renderer/app.tsx
index 2780b1f988..a78f8f67df 100644
--- a/packages/frontend/apps/electron/renderer/app.tsx
+++ b/packages/frontend/apps/electron/renderer/app.tsx
@@ -1,6 +1,3 @@
-import '@affine/component/theme/global.css';
-import '@affine/component/theme/theme.css';
-
import { AffineContext } from '@affine/component/context';
import { GlobalLoading } from '@affine/component/global-loading';
import { AppFallback } from '@affine/core/components/affine/app-container';
diff --git a/packages/frontend/apps/electron/renderer/index.tsx b/packages/frontend/apps/electron/renderer/index.tsx
index f30282d03b..cfbb027e4e 100644
--- a/packages/frontend/apps/electron/renderer/index.tsx
+++ b/packages/frontend/apps/electron/renderer/index.tsx
@@ -1,5 +1,4 @@
import './setup';
-import './global.css';
import { appConfigProxy } from '@affine/core/components/hooks/use-app-config-storage';
import { apis, appInfo, events } from '@affine/electron-api';
diff --git a/packages/frontend/apps/electron/renderer/setup.ts b/packages/frontend/apps/electron/renderer/setup.ts
index 7fc0a00560..9970cae66f 100644
--- a/packages/frontend/apps/electron/renderer/setup.ts
+++ b/packages/frontend/apps/electron/renderer/setup.ts
@@ -1,4 +1,6 @@
-import { setupBlocksuite, setupElectron } from '@affine/core/bootstrap';
+import '@affine/component/theme';
+import './global.css';
+
+import { setupElectron } from '@affine/core/bootstrap';
setupElectron();
-setupBlocksuite();
diff --git a/packages/frontend/apps/electron/renderer/shell/shell.css.ts b/packages/frontend/apps/electron/renderer/shell/app.css.ts
similarity index 100%
rename from packages/frontend/apps/electron/renderer/shell/shell.css.ts
rename to packages/frontend/apps/electron/renderer/shell/app.css.ts
diff --git a/packages/frontend/apps/electron/renderer/shell/app.tsx b/packages/frontend/apps/electron/renderer/shell/app.tsx
new file mode 100644
index 0000000000..1277670172
--- /dev/null
+++ b/packages/frontend/apps/electron/renderer/shell/app.tsx
@@ -0,0 +1,42 @@
+import { ThemeProvider } from '@affine/component/theme-provider';
+import { ShellAppFallback } from '@affine/core/components/affine/app-container';
+import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper';
+import {
+ AppTabsHeader,
+ configureAppTabsHeaderModule,
+} from '@affine/core/modules/app-tabs-header';
+import { configureElectronStateStorageImpls } from '@affine/core/modules/storage';
+import { SplitViewFallback } from '@affine/core/modules/workbench/view/split-view/split-view';
+import {
+ configureGlobalStorageModule,
+ Framework,
+ FrameworkRoot,
+} from '@toeverything/infra';
+
+import * as styles from './app.css';
+
+const framework = new Framework();
+configureGlobalStorageModule(framework);
+configureElectronStateStorageImpls(framework);
+configureAppTabsHeaderModule(framework);
+const frameworkProvider = framework.provider();
+
+export function App() {
+ const { appSettings } = useAppSettingHelper();
+ const translucent =
+ BUILD_CONFIG.isElectron &&
+ environment.isMacOs &&
+ appSettings.enableBlurBackground;
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/frontend/apps/electron/renderer/shell/index.tsx b/packages/frontend/apps/electron/renderer/shell/index.tsx
index 272836273e..3926f92339 100644
--- a/packages/frontend/apps/electron/renderer/shell/index.tsx
+++ b/packages/frontend/apps/electron/renderer/shell/index.tsx
@@ -1,34 +1,17 @@
-import '@affine/component/theme/global.css';
-import '@affine/component/theme/theme.css';
-import '../global.css';
import './setup';
-import { ThemeProvider } from '@affine/component/theme-provider';
-import { configureAppTabsHeaderModule } from '@affine/core/modules/app-tabs-header';
-import { configureElectronStateStorageImpls } from '@affine/core/modules/storage';
import { apis, events } from '@affine/electron-api';
import { createI18n, setUpLanguage } from '@affine/i18n';
-import {
- configureGlobalStorageModule,
- Framework,
- FrameworkRoot,
-} from '@toeverything/infra';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
-import { ShellRoot } from './shell';
+import { App } from './app';
-const framework = new Framework();
-configureGlobalStorageModule(framework);
-configureElectronStateStorageImpls(framework);
-configureAppTabsHeaderModule(framework);
-const frameworkProvider = framework.provider();
-
-async function loadLanguage() {
+function loadLanguage() {
const i18n = createI18n();
document.documentElement.lang = i18n.language;
- await setUpLanguage(i18n);
+ setUpLanguage(i18n).catch(console.error);
}
async function main() {
@@ -48,7 +31,7 @@ async function main() {
events?.ui.onFullScreen(handleFullscreen);
events?.ui.onTabShellViewActiveChange(handleActive);
- await loadLanguage();
+ loadLanguage();
mountApp();
}
@@ -59,11 +42,7 @@ function mountApp() {
}
createRoot(root).render(
-
-
-
-
-
+
);
}
diff --git a/packages/frontend/apps/electron/renderer/shell/setup.ts b/packages/frontend/apps/electron/renderer/shell/setup.ts
index 91daffab1f..5e76f13683 100644
--- a/packages/frontend/apps/electron/renderer/shell/setup.ts
+++ b/packages/frontend/apps/electron/renderer/shell/setup.ts
@@ -1,3 +1,6 @@
+import '@affine/component/theme';
+import '../global.css';
+
import { setupElectron } from '@affine/core/bootstrap';
setupElectron();
diff --git a/packages/frontend/apps/electron/renderer/shell/shell.tsx b/packages/frontend/apps/electron/renderer/shell/shell.tsx
deleted file mode 100644
index 08c50a3643..0000000000
--- a/packages/frontend/apps/electron/renderer/shell/shell.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { ShellAppFallback } from '@affine/core/components/affine/app-container';
-import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper';
-import { AppTabsHeader } from '@affine/core/modules/app-tabs-header';
-import { SplitViewFallback } from '@affine/core/modules/workbench/view/split-view/split-view';
-
-import * as styles from './shell.css';
-
-export function ShellRoot() {
- const { appSettings } = useAppSettingHelper();
- const translucent =
- BUILD_CONFIG.isElectron &&
- environment.isMacOs &&
- appSettings.enableBlurBackground;
- return (
-
- );
-}
diff --git a/packages/frontend/apps/mobile/src/app.tsx b/packages/frontend/apps/mobile/src/app.tsx
index a5c8260091..6c5b3a707d 100644
--- a/packages/frontend/apps/mobile/src/app.tsx
+++ b/packages/frontend/apps/mobile/src/app.tsx
@@ -1,7 +1,3 @@
-import '@affine/component/theme/global.css';
-import '@affine/component/theme/theme.css';
-import '@affine/core/mobile/styles/mobile.css';
-
import { AffineContext } from '@affine/component/context';
import { AppFallback } from '@affine/core/components/affine/app-container';
import { Telemetry } from '@affine/core/components/telemetry';
diff --git a/packages/frontend/apps/mobile/src/setup.ts b/packages/frontend/apps/mobile/src/setup.ts
index ccdc886822..a2a83a681a 100644
--- a/packages/frontend/apps/mobile/src/setup.ts
+++ b/packages/frontend/apps/mobile/src/setup.ts
@@ -1,4 +1,6 @@
-import { setupBlocksuite, setupBrowser } from '@affine/core/bootstrap';
+import '@affine/component/theme';
+import '@affine/core/mobile/styles/mobile.css';
+
+import { setupBrowser } from '@affine/core/bootstrap';
await setupBrowser();
-setupBlocksuite();
diff --git a/packages/frontend/apps/web/src/app.tsx b/packages/frontend/apps/web/src/app.tsx
index db2a418981..53d4c4fa75 100644
--- a/packages/frontend/apps/web/src/app.tsx
+++ b/packages/frontend/apps/web/src/app.tsx
@@ -1,6 +1,3 @@
-import '@affine/component/theme/global.css';
-import '@affine/component/theme/theme.css';
-
import { AffineContext } from '@affine/component/context';
import { GlobalLoading } from '@affine/component/global-loading';
import { AppFallback } from '@affine/core/components/affine/app-container';
diff --git a/packages/frontend/apps/web/src/setup.ts b/packages/frontend/apps/web/src/setup.ts
index ccdc886822..472648fde8 100644
--- a/packages/frontend/apps/web/src/setup.ts
+++ b/packages/frontend/apps/web/src/setup.ts
@@ -1,4 +1,5 @@
-import { setupBlocksuite, setupBrowser } from '@affine/core/bootstrap';
+import '@affine/component/theme';
+
+import { setupBrowser } from '@affine/core/bootstrap';
await setupBrowser();
-setupBlocksuite();
diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json
index 170f58f28a..e370e32953 100644
--- a/packages/frontend/component/package.json
+++ b/packages/frontend/component/package.json
@@ -4,7 +4,7 @@
"main": "./src/index.ts",
"exports": {
".": "./src/index.ts",
- "./theme/*": "./src/theme/*",
+ "./theme": "./src/theme/index.ts",
"./ui/*": "./src/ui/*/index.ts",
"./*": "./src/components/*/index.tsx"
},
diff --git a/packages/frontend/component/src/theme/global.css b/packages/frontend/component/src/theme/global.css
index eaab43b367..bf67aaeb41 100644
--- a/packages/frontend/component/src/theme/global.css
+++ b/packages/frontend/component/src/theme/global.css
@@ -1,6 +1,3 @@
-@import './fonts.css';
-@import '@toeverything/theme/style.css';
-
* {
-webkit-overflow-scrolling: touch;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
diff --git a/packages/frontend/component/src/theme/index.ts b/packages/frontend/component/src/theme/index.ts
new file mode 100644
index 0000000000..591cc37e62
--- /dev/null
+++ b/packages/frontend/component/src/theme/index.ts
@@ -0,0 +1,4 @@
+import '@toeverything/theme/style.css';
+import './fonts.css';
+import './global.css';
+import './theme.css';
diff --git a/packages/frontend/component/src/theme/theme.css.ts b/packages/frontend/component/src/theme/theme.css.ts
index e44c4c749a..6c6c9ccd68 100644
--- a/packages/frontend/component/src/theme/theme.css.ts
+++ b/packages/frontend/component/src/theme/theme.css.ts
@@ -6,9 +6,3 @@ globalStyle('body', {
fontFamily: cssVar('fontFamily'),
fontSize: cssVar('fontBase'),
});
-
-if (process.env.NODE_ENV === 'development') {
- globalStyle('.undefined', {
- border: '5px solid red !important',
- });
-}
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-button.ts b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-button.ts
index e77c1b4774..f7efc40eb1 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-button.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-button.ts
@@ -10,7 +10,7 @@ import { createLitPortal, HoverController } from '@blocksuite/blocks';
import { assertExists } from '@blocksuite/global/utils';
import { flip, offset } from '@floating-ui/dom';
import { css, html, LitElement, nothing } from 'lit';
-import { customElement, property, query } from 'lit/decorators.js';
+import { property, query } from 'lit/decorators.js';
import { ref } from 'lit/directives/ref.js';
import { styleMap } from 'lit/directives/style-map.js';
@@ -38,7 +38,6 @@ export type AskAIButtonOptions = {
panelWidth?: number;
};
-@customElement('ask-ai-button')
export class AskAIButton extends WithDisposable(LitElement) {
get _edgeless() {
const rootService = getRootService(this.host);
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-panel.ts b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-panel.ts
index 25a60d4cd4..086aaa9b47 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-panel.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/ask-ai-panel.ts
@@ -5,12 +5,11 @@ import {
scrollbarStyle,
} from '@blocksuite/blocks';
import { css, html, LitElement } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import { getRootService } from '../../utils/selection-utils';
-@customElement('ask-ai-panel')
export class AskAIPanel extends WithDisposable(LitElement) {
static override styles = css`
:host {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/chat-action-list.ts b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/chat-action-list.ts
index 00727488f4..e3e29df335 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/chat-action-list.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/chat-action-list.ts
@@ -5,14 +5,13 @@ import type {
} from '@blocksuite/block-std';
import { type ImageSelection, NotificationProvider } from '@blocksuite/blocks';
import { css, html, LitElement, nothing } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { repeat } from 'lit/directives/repeat.js';
import { insertBelow } from '../../utils/editor-actions';
import type { ChatAction } from '../chat-actions-handle';
-@customElement('chat-action-list')
export class ChatActionList extends LitElement {
static override styles = css`
.actions-container {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/copy-more.ts b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/copy-more.ts
index ae5454e4c5..7dc9bd75f8 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/_common/components/copy-more.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/_common/components/copy-more.ts
@@ -11,7 +11,7 @@ import {
} from '@blocksuite/blocks';
import { noop } from '@blocksuite/global/utils';
import { css, html, LitElement, nothing, type PropertyValues } from 'lit';
-import { customElement, property, query, state } from 'lit/decorators.js';
+import { property, query, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { type ChatAction } from '../../_common/chat-actions-handle';
@@ -20,7 +20,6 @@ import { copyText } from '../../utils/editor-actions';
noop(Tooltip);
-@customElement('chat-copy-more')
export class ChatCopyMore extends WithDisposable(LitElement) {
static override styles = css`
.copy-more {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/action-wrapper.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/action-wrapper.ts
index 5b6e733a22..49a3955968 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/action-wrapper.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/action-wrapper.ts
@@ -1,7 +1,7 @@
import type { EditorHost } from '@blocksuite/block-std';
import { WithDisposable } from '@blocksuite/block-std';
import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
-import { customElement, property, state } from 'lit/decorators.js';
+import { property, state } from 'lit/decorators.js';
import {
ActionIcon,
@@ -59,7 +59,6 @@ const icons: Record> = {
'Convert to sticker': AIImageIcon,
};
-@customElement('action-wrapper')
export class ActionWrapper extends WithDisposable(LitElement) {
static override styles = css`
.action-name {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/chat-text.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/chat-text.ts
index 1ceeb017a6..5633164cfa 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/chat-text.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/chat-text.ts
@@ -3,11 +3,10 @@ import './action-wrapper';
import type { EditorHost } from '@blocksuite/block-std';
import { ShadowlessElement, WithDisposable } from '@blocksuite/block-std';
import { html, nothing } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { createTextRenderer } from '../../messages/text';
import { renderImages } from '../components/images';
-@customElement('chat-text')
export class ChatText extends WithDisposable(ShadowlessElement) {
@property({ attribute: false })
accessor host!: EditorHost;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image-to-text.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image-to-text.ts
index 9606ad28b3..4ffde9e37b 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image-to-text.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image-to-text.ts
@@ -3,13 +3,12 @@ import './action-wrapper';
import type { EditorHost } from '@blocksuite/block-std';
import { ShadowlessElement, WithDisposable } from '@blocksuite/block-std';
import { html, nothing } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import type { ChatAction } from '../chat-context';
import { renderImages } from '../components/images';
-@customElement('action-image-to-text')
export class ActionImageToText extends WithDisposable(ShadowlessElement) {
@property({ attribute: false })
accessor item!: ChatAction;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image.ts
index 41de61f3cb..2dbb400595 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/image.ts
@@ -3,13 +3,12 @@ import './action-wrapper';
import type { EditorHost } from '@blocksuite/block-std';
import { ShadowlessElement, WithDisposable } from '@blocksuite/block-std';
import { html, nothing } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import type { ChatAction } from '../chat-context';
import { renderImages } from '../components/images';
-@customElement('action-image')
export class ActionImage extends WithDisposable(ShadowlessElement) {
@property({ attribute: false })
accessor item!: ChatAction;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/make-real.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/make-real.ts
index 4dda95cea8..72e54a8d12 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/make-real.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/make-real.ts
@@ -3,13 +3,12 @@ import './action-wrapper';
import type { EditorHost } from '@blocksuite/block-std';
import { ShadowlessElement, WithDisposable } from '@blocksuite/block-std';
import { html } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import { createIframeRenderer } from '../../messages/wrapper';
import type { ChatAction } from '../chat-context';
-@customElement('action-make-real')
export class ActionMakeReal extends WithDisposable(ShadowlessElement) {
@property({ attribute: false })
accessor item!: ChatAction;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/mindmap.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/mindmap.ts
index 4dbc6f7a60..a82c3b594b 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/mindmap.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/mindmap.ts
@@ -5,14 +5,13 @@ import { ShadowlessElement, WithDisposable } from '@blocksuite/block-std';
import { MiniMindmapPreview } from '@blocksuite/blocks';
import { noop } from '@blocksuite/global/utils';
import { html } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import type { ChatAction } from '../chat-context';
noop(MiniMindmapPreview);
-@customElement('action-mindmap')
export class ActionMindmap extends WithDisposable(ShadowlessElement) {
@property({ attribute: false })
accessor item!: ChatAction;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/slides.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/slides.ts
index 9f2bd05f3f..fdf137ba68 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/slides.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/slides.ts
@@ -4,12 +4,11 @@ import '../../messages/slides-renderer';
import type { EditorHost } from '@blocksuite/block-std';
import { ShadowlessElement, WithDisposable } from '@blocksuite/block-std';
import { html, nothing } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import type { ChatAction } from '../chat-context';
-@customElement('action-slides')
export class ActionSlides extends WithDisposable(ShadowlessElement) {
@property({ attribute: false })
accessor item!: ChatAction;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/text.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/text.ts
index c1c04f2868..9715b4c7de 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/text.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/actions/text.ts
@@ -3,13 +3,12 @@ import './action-wrapper';
import type { EditorHost } from '@blocksuite/block-std';
import { WithDisposable } from '@blocksuite/block-std';
import { css, html, LitElement } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import { createTextRenderer } from '../../messages/text';
import type { ChatAction } from '../chat-context';
-@customElement('action-text')
export class ActionText extends WithDisposable(LitElement) {
static override styles = css`
.original-text {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/ai-loading.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/ai-loading.ts
index 70bb2ab984..de4da0d2af 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/ai-loading.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/ai-loading.ts
@@ -1,10 +1,9 @@
import { WithDisposable } from '@blocksuite/block-std';
import { css, html, LitElement } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { AIStarIconWithAnimation } from '../_common/icons';
-@customElement('ai-loading')
export class AILoading extends WithDisposable(LitElement) {
static override styles = css`
:host {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts
index c2bf405599..63c48be12d 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-cards.ts
@@ -15,7 +15,7 @@ import {
type PropertyValues,
type TemplateResult,
} from 'lit';
-import { customElement, property, state } from 'lit/decorators.js';
+import { property, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
@@ -94,7 +94,6 @@ type Card = CardText | CardImage | CardBlock;
const MAX_CARDS = 3;
-@customElement('chat-cards')
export class ChatCards extends WithDisposable(LitElement) {
static override styles = css`
:host {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts
index 2bc9be5426..7b57825d9c 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-input.ts
@@ -3,7 +3,7 @@ import { WithDisposable } from '@blocksuite/block-std';
import { type AIError, openFileOrFiles } from '@blocksuite/blocks';
import { assertExists } from '@blocksuite/global/utils';
import { css, html, LitElement, nothing } from 'lit';
-import { customElement, property, query, state } from 'lit/decorators.js';
+import { property, query, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import {
@@ -25,7 +25,6 @@ function getFirstTwoLines(text: string) {
return lines.slice(0, 2);
}
-@customElement('chat-panel-input')
export class ChatPanelInput extends WithDisposable(LitElement) {
static override styles = css`
.chat-panel-input {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts
index 08bde98073..990cf39572 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts
@@ -23,7 +23,7 @@ import {
UnauthorizedError,
} from '@blocksuite/blocks';
import { css, html, nothing, type PropertyValues } from 'lit';
-import { customElement, property, query, state } from 'lit/decorators.js';
+import { property, query, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
@@ -38,7 +38,6 @@ import type { ChatContextValue, ChatItem, ChatMessage } from './chat-context';
import { HISTORY_IMAGE_ACTIONS } from './const';
import { AIPreloadConfig } from './preload-config';
-@customElement('chat-panel-messages')
export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
static override styles = css`
chat-panel-messages {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts
index 33521b8e25..eecec60a47 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/index.ts
@@ -7,7 +7,7 @@ import { NotificationProvider } from '@blocksuite/blocks';
import { debounce } from '@blocksuite/global/utils';
import type { Doc } from '@blocksuite/store';
import { css, html, type PropertyValues } from 'lit';
-import { customElement, property, state } from 'lit/decorators.js';
+import { property, state } from 'lit/decorators.js';
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
import { AIHelpIcon, SmallHintIcon } from '../_common/icons';
@@ -19,7 +19,6 @@ import {
import type { ChatAction, ChatContextValue, ChatItem } from './chat-context';
import type { ChatPanelMessages } from './chat-panel-messages';
-@customElement('chat-panel')
export class ChatPanel extends WithDisposable(ShadowlessElement) {
static override styles = css`
chat-panel {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/index.ts b/packages/frontend/core/src/blocksuite/presets/ai/index.ts
index 2d804bc527..afccac1808 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/index.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/index.ts
@@ -6,3 +6,4 @@ export * from './entries/index';
export * from './messages/index';
export { AIChatBlockPeekViewTemplate } from './peek-view/chat-block-peek-view';
export * from './provider';
+export * from './setup';
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/messages/error.ts b/packages/frontend/core/src/blocksuite/presets/ai/messages/error.ts
index 0340b5ff35..859001a3eb 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/messages/error.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/messages/error.ts
@@ -5,14 +5,13 @@ import {
UnauthorizedError,
} from '@blocksuite/blocks';
import { html, LitElement, nothing, type TemplateResult } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import { ErrorTipIcon } from '../_common/icons';
import { AIProvider } from '../provider';
-@customElement('ai-error-wrapper')
-class AIErrorWrapper extends WithDisposable(LitElement) {
+export class AIErrorWrapper extends WithDisposable(LitElement) {
@property({ attribute: false })
accessor text!: TemplateResult<1>;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts b/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts
index cac9d6f5c5..8f99e610a6 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/messages/slides-renderer.ts
@@ -8,7 +8,7 @@ import { AffineSchemas } from '@blocksuite/blocks/schemas';
import type { Doc } from '@blocksuite/store';
import { DocCollection, Schema } from '@blocksuite/store';
import { css, html, LitElement, nothing } from 'lit';
-import { customElement, property, query } from 'lit/decorators.js';
+import { property, query } from 'lit/decorators.js';
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
import { getAIPanel } from '../ai-panel';
@@ -48,7 +48,6 @@ export const createSlidesRenderer: (
};
};
-@customElement('ai-slides-renderer')
export class AISlidesRenderer extends WithDisposable(LitElement) {
static override styles = css``;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/messages/text.ts b/packages/frontend/core/src/blocksuite/presets/ai/messages/text.ts
index 37aee626e0..894c40576d 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/messages/text.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/messages/text.ts
@@ -15,7 +15,7 @@ import {
} from '@blocksuite/blocks';
import { BlockViewType, type Doc, type Query } from '@blocksuite/store';
import { css, html, LitElement, type PropertyValues } from 'lit';
-import { customElement, property, query } from 'lit/decorators.js';
+import { property, query } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { keyed } from 'lit/directives/keyed.js';
@@ -75,7 +75,6 @@ type TextRendererOptions = {
customHeading?: boolean;
};
-@customElement('ai-answer-text')
export class AIAnswerText extends WithDisposable(LitElement) {
static override styles = css`
.ai-answer-text-editor.affine-page-viewport {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/messages/wrapper.ts b/packages/frontend/core/src/blocksuite/presets/ai/messages/wrapper.ts
index f4f23ca39a..7e115746be 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/messages/wrapper.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/messages/wrapper.ts
@@ -1,7 +1,7 @@
import type { EditorHost } from '@blocksuite/block-std';
import type { AffineAIPanelWidgetConfig } from '@blocksuite/blocks';
import { css, html, LitElement, nothing } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
import { getAIPanel } from '../ai-panel';
import { preprocessHtml } from '../utils/html';
@@ -10,7 +10,6 @@ type AIAnswerWrapperOptions = {
height: number;
};
-@customElement('ai-answer-wrapper')
export class AIAnswerWrapper extends LitElement {
static override styles = css`
:host {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-input.ts b/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-input.ts
index 98f3bc5522..9889d21f73 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-input.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-input.ts
@@ -2,7 +2,7 @@ import type { EditorHost } from '@blocksuite/block-std';
import { type AIError, openFileOrFiles } from '@blocksuite/blocks';
import { type ChatMessage } from '@blocksuite/presets';
import { css, html, LitElement, nothing } from 'lit';
-import { customElement, property, query, state } from 'lit/decorators.js';
+import { property, query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { repeat } from 'lit/directives/repeat.js';
@@ -20,7 +20,6 @@ import type { ChatContext } from './types';
const MaximumImageCount = 8;
-@customElement('chat-block-input')
export class ChatBlockInput extends LitElement {
static override styles = css`
:host {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-peek-view.ts b/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-peek-view.ts
index 2c0c7d6a86..c3aaa953e9 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-peek-view.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/peek-view/chat-block-peek-view.ts
@@ -19,7 +19,7 @@ import {
ChatMessagesSchema,
} from '@blocksuite/presets';
import { html, LitElement, nothing } from 'lit';
-import { customElement, property, query, state } from 'lit/decorators.js';
+import { property, query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { repeat } from 'lit/directives/repeat.js';
@@ -35,7 +35,6 @@ import { PeekViewStyles } from './styles';
import type { ChatContext } from './types';
import { calcChildBound } from './utils';
-@customElement('ai-chat-block-peek-view')
export class AIChatBlockPeekView extends LitElement {
static override styles = PeekViewStyles;
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/peek-view/date-time.ts b/packages/frontend/core/src/blocksuite/presets/ai/peek-view/date-time.ts
index 914e471335..b296b33cf6 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/peek-view/date-time.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/peek-view/date-time.ts
@@ -1,8 +1,7 @@
import { i18nTime } from '@affine/i18n';
import { css, html, LitElement } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
+import { property } from 'lit/decorators.js';
-@customElement('date-time')
export class DateTime extends LitElement {
static override styles = css`
:host {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/setup.ts b/packages/frontend/core/src/blocksuite/presets/ai/setup.ts
new file mode 100644
index 0000000000..5e6d41ae4b
--- /dev/null
+++ b/packages/frontend/core/src/blocksuite/presets/ai/setup.ts
@@ -0,0 +1,50 @@
+import { AskAIButton } from './_common/components/ask-ai-button';
+import { AskAIPanel } from './_common/components/ask-ai-panel';
+import { ChatActionList } from './_common/components/chat-action-list';
+import { ChatCopyMore } from './_common/components/copy-more';
+import { ChatPanel } from './chat-panel';
+import { ActionWrapper } from './chat-panel/actions/action-wrapper';
+import { ChatText } from './chat-panel/actions/chat-text';
+import { ActionImage } from './chat-panel/actions/image';
+import { ActionImageToText } from './chat-panel/actions/image-to-text';
+import { ActionMakeReal } from './chat-panel/actions/make-real';
+import { ActionMindmap } from './chat-panel/actions/mindmap';
+import { ActionSlides } from './chat-panel/actions/slides';
+import { ActionText } from './chat-panel/actions/text';
+import { AILoading } from './chat-panel/ai-loading';
+import { ChatCards } from './chat-panel/chat-cards';
+import { ChatPanelInput } from './chat-panel/chat-panel-input';
+import { ChatPanelMessages } from './chat-panel/chat-panel-messages';
+import { AIAnswerText, AIAnswerWrapper } from './messages';
+import { AIErrorWrapper } from './messages/error';
+import { AISlidesRenderer } from './messages/slides-renderer';
+import { ChatBlockInput } from './peek-view/chat-block-input';
+import { AIChatBlockPeekView } from './peek-view/chat-block-peek-view';
+import { DateTime } from './peek-view/date-time';
+
+export function registerAICustomComponents() {
+ customElements.define('ask-ai-button', AskAIButton);
+ customElements.define('ask-ai-panel', AskAIPanel);
+ customElements.define('chat-action-list', ChatActionList);
+ customElements.define('chat-copy-more', ChatCopyMore);
+ customElements.define('action-wrapper', ActionWrapper);
+ customElements.define('chat-text', ChatText);
+ customElements.define('action-image-to-text', ActionImageToText);
+ customElements.define('action-image', ActionImage);
+ customElements.define('action-make-real', ActionMakeReal);
+ customElements.define('action-mindmap', ActionMindmap);
+ customElements.define('action-slides', ActionSlides);
+ customElements.define('action-text', ActionText);
+ customElements.define('ai-loading', AILoading);
+ customElements.define('chat-cards', ChatCards);
+ customElements.define('chat-panel-input', ChatPanelInput);
+ customElements.define('chat-panel-messages', ChatPanelMessages);
+ customElements.define('chat-panel', ChatPanel);
+ customElements.define('ai-error-wrapper', AIErrorWrapper);
+ customElements.define('ai-slides-renderer', AISlidesRenderer);
+ customElements.define('ai-answer-wrapper', AIAnswerWrapper);
+ customElements.define('ai-answer-text', AIAnswerText);
+ customElements.define('chat-block-input', ChatBlockInput);
+ customElements.define('ai-chat-block-peek-view', AIChatBlockPeekView);
+ customElements.define('date-time', DateTime);
+}
diff --git a/packages/frontend/core/src/bootstrap/blocksuite.ts b/packages/frontend/core/src/bootstrap/blocksuite.ts
deleted file mode 100644
index 2ee114d1c9..0000000000
--- a/packages/frontend/core/src/bootstrap/blocksuite.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { builtInTemplates as builtInEdgelessTemplates } from '@affine/templates/edgeless';
-import { builtInTemplates as builtInStickersTemplates } from '@affine/templates/stickers';
-import type { TemplateManager } from '@blocksuite/blocks';
-import { EdgelessTemplatePanel } from '@blocksuite/blocks';
-
-export function setupBlocksuite() {
- EdgelessTemplatePanel.templates.extend(
- builtInStickersTemplates as TemplateManager
- );
- EdgelessTemplatePanel.templates.extend(
- builtInEdgelessTemplates as TemplateManager
- );
-}
diff --git a/packages/frontend/core/src/bootstrap/index.ts b/packages/frontend/core/src/bootstrap/index.ts
index d70f4baa94..6ef4229a54 100644
--- a/packages/frontend/core/src/bootstrap/index.ts
+++ b/packages/frontend/core/src/bootstrap/index.ts
@@ -12,5 +12,3 @@ export async function setupBrowser() {
await polyfillBrowser();
setupEnvironment();
}
-
-export { setupBlocksuite } from './blocksuite';
diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/edgeless/snapshot.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/edgeless/snapshot.tsx
index 23e89d4e17..96380a9f93 100644
--- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/edgeless/snapshot.tsx
+++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/edgeless/snapshot.tsx
@@ -1,5 +1,4 @@
import { Skeleton } from '@affine/component';
-import { getFontConfigExtension } from '@affine/core/components/blocksuite/block-suite-editor';
import type { EditorSettingSchema } from '@affine/core/modules/editor-settting';
import { EditorSettingService } from '@affine/core/modules/editor-settting';
import type { EditorHost } from '@blocksuite/block-std';
@@ -72,10 +71,7 @@ export const EdgelessSnapshot = (props: Props) => {
const editorHost = new BlockStdScope({
doc,
- extensions: [
- ...SpecProvider.getInstance().getSpec('edgeless:preview').value,
- getFontConfigExtension(),
- ],
+ extensions: SpecProvider.getInstance().getSpec('edgeless:preview').value,
}).render();
docRef.current = doc;
editorHostRef.current = editorHost;
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/index.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/index.ts
similarity index 65%
rename from packages/frontend/core/src/components/blocksuite/block-suite-editor/index.tsx
rename to packages/frontend/core/src/components/blocksuite/block-suite-editor/index.ts
index 89f05ebff3..d3be9554de 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/index.tsx
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/index.ts
@@ -1,13 +1,16 @@
-export * from './blocksuite-editor';
-export { getFontConfigExtension } from './specs/font-extension';
-
+import { registerAICustomComponents } from '@affine/core/blocksuite/presets/ai';
import { effects as blocksEffects } from '@blocksuite/blocks/effects';
import { effects as presetsEffects } from '@blocksuite/presets/effects';
import { setupAIProvider } from './ai/setup-provider';
+import { effects as edgelessEffects } from './specs/edgeless';
import { effects as patchEffects } from './specs/preview';
blocksEffects();
presetsEffects();
patchEffects();
setupAIProvider();
+edgelessEffects();
+registerAICustomComponents();
+
+export * from './blocksuite-editor';
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts
index f8257c0f37..3e4c1c6e03 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts
@@ -55,6 +55,7 @@ export function createPageRootBlockSpec(
return [
enableAI ? AIPageRootBlockSpec : PageRootBlockSpec,
FontLoaderService,
+ getFontConfigExtension(),
getTelemetryExtension(),
getEditorConfigExtension(framework),
].flat();
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts
index 61034af30d..2f109893cc 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts
@@ -1,8 +1,12 @@
+import { builtInTemplates as builtInEdgelessTemplates } from '@affine/templates/edgeless';
+import { builtInTemplates as builtInStickersTemplates } from '@affine/templates/stickers';
import type { ExtensionType } from '@blocksuite/block-std';
+import type { TemplateManager } from '@blocksuite/blocks';
import {
EdgelessNoteBlockSpec,
EdgelessSurfaceBlockSpec,
EdgelessSurfaceRefBlockSpec,
+ EdgelessTemplatePanel,
EdgelessTextBlockSpec,
FrameBlockSpec,
} from '@blocksuite/blocks';
@@ -26,3 +30,12 @@ export function createEdgelessModeSpecs(
createEdgelessRootBlockSpec(framework, enableAI),
].flat();
}
+
+export function effects() {
+ EdgelessTemplatePanel.templates.extend(
+ builtInStickersTemplates as TemplateManager
+ );
+ EdgelessTemplatePanel.templates.extend(
+ builtInEdgelessTemplates as TemplateManager
+ );
+}
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts
index 8f9da9114f..d49719116f 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/preview.ts
@@ -2,7 +2,12 @@ import type { ExtensionType } from '@blocksuite/block-std';
import { SpecProvider } from '@blocksuite/blocks';
import { AIChatBlockSpec } from '@blocksuite/presets';
-const CustomSpecs: ExtensionType[] = [AIChatBlockSpec].flat();
+import { getFontConfigExtension } from './font-extension';
+
+const CustomSpecs: ExtensionType[] = [
+ AIChatBlockSpec,
+ getFontConfigExtension(),
+].flat();
function patchPreviewSpec(id: string, specs: ExtensionType[]) {
const specProvider = SpecProvider.getInstance();