diff --git a/.all-contributorsrc b/.all-contributorsrc
index 9f85871a65..8993984505 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -10,6 +10,7 @@
"commit": false,
"commitConvention": "angular",
"contributorsPerLine": 7,
+ "badgeTemplate": "\n[all-contributors-badge]: https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg?style=flat-square\n",
"contributors": [
{
"login": "darkskygit",
@@ -229,6 +230,79 @@
"contributions": [
"doc"
]
+ },
+ {
+ "login": "liby",
+ "name": "Bryan Lee",
+ "avatar_url": "https://avatars.githubusercontent.com/u/38807139?v=4",
+ "profile": "https://liby.github.io/notes",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "chenmoonmo",
+ "name": "Simon Li",
+ "avatar_url": "https://avatars.githubusercontent.com/u/36295999?v=4",
+ "profile": "https://github.com/chenmoonmo",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "githbq",
+ "name": "Bob Hu",
+ "avatar_url": "https://avatars.githubusercontent.com/u/10009709?v=4",
+ "profile": "https://github.com/githbq",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "lucky-chap",
+ "name": "Quavo",
+ "avatar_url": "https://avatars.githubusercontent.com/u/67266933?v=4",
+ "profile": "https://quavo.vercel.app/",
+ "contributions": [
+ "doc"
+ ]
+ },
+ {
+ "login": "LuciNyan",
+ "name": "子瞻 Luci",
+ "avatar_url": "https://avatars.githubusercontent.com/u/22126563?v=4",
+ "profile": "https://github.com/LuciNyan",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "m1911star",
+ "name": "Horus",
+ "avatar_url": "https://avatars.githubusercontent.com/u/4948120?v=4",
+ "profile": "http://blog.ipili.me/",
+ "contributions": [
+ "code",
+ "platform"
+ ]
+ },
+ {
+ "login": "fanshyiis",
+ "name": "Super.x",
+ "avatar_url": "https://avatars.githubusercontent.com/u/15103283?v=4",
+ "profile": "https://segmentfault.com/u/qzuser_584786517d31a",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "wangyu-1999",
+ "name": "Wang Yu",
+ "avatar_url": "https://avatars.githubusercontent.com/u/80874770?v=4",
+ "profile": "https://wangyu-1999.github.io/",
+ "contributions": [
+ "code"
+ ]
}
]
}
diff --git a/.cz-config.js b/.cz-config.js
index e282d831ee..a0608d5afa 100644
--- a/.cz-config.js
+++ b/.cz-config.js
@@ -26,7 +26,7 @@ module.exports = {
],
scopes: [
{ name: 'selection' },
- { name: 'whiteboard' },
+ { name: 'edgeless' },
{ name: 'point' },
{ name: 'group' },
{ name: 'page' },
diff --git a/.env b/.env
index 30dbae3055..63e14bc841 100644
--- a/.env
+++ b/.env
@@ -1,4 +1,5 @@
# use for download icon from figma
+
FIGMA_TOKEN
NODE_ENV
AFFINE_FEATURE_FLAG_TOKEN
diff --git a/.eslintrc.json b/.eslintrc.json
index 89fe5429c2..549f14aed9 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -260,6 +260,12 @@
]
}
},
+ {
+ "files": ["index.tsx", "index.*.tsx"],
+ "rules": {
+ "filename-rules/match": "off"
+ }
+ },
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nrwl/nx/typescript"],
diff --git a/.husky/pre-commit b/.husky/pre-commit
index deb953a84e..54bcfe98fa 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -3,6 +3,4 @@
# npx lint-staged
-pnpm run lint:with-cache
-pnpm run check
pnpm run format:ci
diff --git a/.husky/pre-push b/.husky/pre-push
index 741e9183e4..9c7674d585 100755
--- a/.husky/pre-push
+++ b/.husky/pre-push
@@ -11,4 +11,4 @@ if test $current_branch != $default_branch; then
exit 0
fi
-npm run type:check
+pnpm run build:check
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 375ba3b6e0..e69da8bc93 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,6 +2,7 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file",
+ "editor.codeActionsOnSave": ["source.fixAll", "source.organizeImports"],
"prettier.prettierPath": "./node_modules/prettier",
"cSpell.words": [
"AUTOINCREMENT",
diff --git a/README.md b/README.md
index 30d99c7179..396bfe008e 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ See https://github.com/all-?/all-contributors/issues/361#issuecomment-637166066
-->
-[all-contributors-badge]: https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square
+[all-contributors-badge]: https://img.shields.io/badge/all_contributors-31-orange.svg?style=flat-square
@@ -33,13 +33,19 @@ See https://github.com/all-?/all-contributors/issues/361#issuecomment-637166066
- Website •
- Discord •
- Twitter •
- Medium •
- Telegram
+
+
+
+
+
+
+
+
+
+
+
# Stay Up-to-Date and Support Us
@@ -117,7 +123,7 @@ Please view the path Contribute-to-AFFiNE/Software-Contributions/Quick-Start in
# Roadmap
-Coming Soon...
+Yes! Permanent storage, collaboration, stable release is planned! Check it [here](https://github.com/toeverything/AFFiNE/issues/293)
# Releases
@@ -218,6 +224,16 @@ For help, discussion about best practices, or any other conversation that would
Weston Graham 📖
pointmax 📖
+ Bryan Lee 💻
+ Simon Li 💻
+ Bob Hu 💻
+ Quavo 📖
+ 子瞻 Luci 💻
+
+
+ Horus 💻 📦
+ Super.x 💻
+ Wang Yu 💻
diff --git a/apps/keck/src/index.ts b/apps/keck/src/index.ts
index 31dadb7893..d924f1d780 100644
--- a/apps/keck/src/index.ts
+++ b/apps/keck/src/index.ts
@@ -7,8 +7,8 @@ import firebaseAuth = require('firebase-admin/auth');
import LRUCache = require('lru-cache');
import nanoid = require('nanoid');
-import { handleConnection } from './utils';
import { URL } from 'url';
+import { handleConnection } from './utils';
if (process.env.NODE_ENV !== 'development') {
firebaseApp.initializeApp({
diff --git a/apps/ligo-virgo-e2e/src/integration/app.spec.ts b/apps/ligo-virgo-e2e/src/integration/app.spec.ts
index 0d3bae5e04..520bd9ada3 100644
--- a/apps/ligo-virgo-e2e/src/integration/app.spec.ts
+++ b/apps/ligo-virgo-e2e/src/integration/app.spec.ts
@@ -1,10 +1,10 @@
-import { getTitle, getBoard } from '../support/app.po';
+import { getBoard, getTitle } from '../support/app.po';
describe('ligo-virgo', () => {
beforeEach(() => cy.visit('/'));
it('basic load check', () => {
- getTitle().contains('👋 Get Started with AFFINE');
+ getTitle().contains('👋 Get Started with AFFiNE');
cy.get('.block_container').contains('The Essentials');
diff --git a/apps/ligo-virgo-e2e/src/support/commands.ts b/apps/ligo-virgo-e2e/src/support/commands.ts
index 4200179bac..395bb4a20f 100644
--- a/apps/ligo-virgo-e2e/src/support/commands.ts
+++ b/apps/ligo-virgo-e2e/src/support/commands.ts
@@ -12,14 +12,14 @@
declare namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable {
- login(email: string, password: string): void;
+ // login(email: string, password: string): void;
}
}
//
// -- This is a parent command --
-Cypress.Commands.add('login', (email, password) => {
- console.log('Custom command example: Login', email, password);
-});
+// Cypress.Commands.add('login', (email, password) => {
+// console.log('Custom command example: Login', email, password);
+// });
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
diff --git a/apps/ligo-virgo/src/index.tsx b/apps/ligo-virgo/src/index.tsx
index 14e33ec10f..19d5446ee2 100644
--- a/apps/ligo-virgo/src/index.tsx
+++ b/apps/ligo-virgo/src/index.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable filename-rules/match */
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
diff --git a/apps/ligo-virgo/src/pages/AppContainer.tsx b/apps/ligo-virgo/src/pages/AppContainer.tsx
index 18caa7d209..05d7fa4eef 100644
--- a/apps/ligo-virgo/src/pages/AppContainer.tsx
+++ b/apps/ligo-virgo/src/pages/AppContainer.tsx
@@ -1,11 +1,20 @@
-import { Outlet } from 'react-router-dom';
-
+import { css, Global } from '@emotion/react';
+import { LayoutHeader, SettingsSidebar } from '@toeverything/components/layout';
import { styled } from '@toeverything/components/ui';
-import { SettingsSidebar, LayoutHeader } from '@toeverything/components/layout';
+import { Outlet } from 'react-router-dom';
export function LigoVirgoRootContainer() {
return (
-
+ <>
+
@@ -13,7 +22,7 @@ export function LigoVirgoRootContainer() {
-
+ >
);
}
@@ -23,12 +32,6 @@ const StyledMainContainer = styled('div')({
overflowY: 'hidden',
});
-const StyledRootContainer = styled('div')({
- display: 'flex',
- flexDirection: 'row',
- height: '100vh',
-});
-
const StyledContentContainer = styled('div')({
flex: 'auto',
display: 'flex',
diff --git a/apps/ligo-virgo/src/pages/AppRoutes.tsx b/apps/ligo-virgo/src/pages/AppRoutes.tsx
index 2c79a81259..c27ae6a76f 100644
--- a/apps/ligo-virgo/src/pages/AppRoutes.tsx
+++ b/apps/ligo-virgo/src/pages/AppRoutes.tsx
@@ -1,20 +1,20 @@
-import { Routes, Route, Navigate } from 'react-router-dom';
+import { Navigate, Route, Routes } from 'react-router-dom';
+import { Login } from './account';
import Agenda from './agenda';
-import { WorkspaceContainer } from './workspace';
+import { LigoVirgoRootContainer } from './AppContainer';
import Recent from './recent';
+import { RoutePrivate } from './RoutePrivate';
+import { RoutePublicAutoLogin } from './RoutePublicAutoLogin';
import Search from './search';
import Settings from './settings';
import Shared from './shared';
import Starred from './starred';
-import { Login } from './account';
import { PageNotFound } from './status/page-not-found';
import { WorkspaceNotFound } from './status/workspace-not-found';
-import { RoutePrivate } from './RoutePrivate';
-import { RoutePublicAutoLogin } from './RoutePublicAutoLogin';
import { Tools } from './tools';
-import { LigoVirgoRootContainer } from './AppContainer';
import { UIPage } from './ui';
+import { WorkspaceContainer } from './workspace';
export function LigoVirgoRoutes() {
return (
diff --git a/apps/ligo-virgo/src/pages/RoutePrivate.tsx b/apps/ligo-virgo/src/pages/RoutePrivate.tsx
index a7cedac934..76c254610d 100644
--- a/apps/ligo-virgo/src/pages/RoutePrivate.tsx
+++ b/apps/ligo-virgo/src/pages/RoutePrivate.tsx
@@ -1,6 +1,6 @@
import { Navigate, useLocation } from 'react-router-dom';
-import { PageLoading, Error } from '@toeverything/components/account';
+import { PageLoading } from '@toeverything/components/account';
import { useUserAndSpaces } from '@toeverything/datasource/state';
export type RoutePrivateProps = {
diff --git a/apps/ligo-virgo/src/pages/agenda/index.tsx b/apps/ligo-virgo/src/pages/agenda/index.tsx
index 23f478ad5f..6a0f4bf01e 100644
--- a/apps/ligo-virgo/src/pages/agenda/index.tsx
+++ b/apps/ligo-virgo/src/pages/agenda/index.tsx
@@ -1,10 +1,10 @@
-import { Routes, Route } from 'react-router-dom';
+import { Route, Routes } from 'react-router-dom';
-import Container from './container';
import Calendar from './calendar';
+import Container from './container';
+import Home from './home';
import Tasks from './tasks';
import Today from './today';
-import Home from './home';
export default function AgendaContainer() {
return (
diff --git a/apps/ligo-virgo/src/pages/tools/icons/Icons.tsx b/apps/ligo-virgo/src/pages/tools/icons/Icons.tsx
index 10ce453162..48059b4772 100644
--- a/apps/ligo-virgo/src/pages/tools/icons/Icons.tsx
+++ b/apps/ligo-virgo/src/pages/tools/icons/Icons.tsx
@@ -1,6 +1,6 @@
-import { type ComponentType, useRef } from 'react';
import * as uiIcons from '@toeverything/components/icons';
import { message, styled } from '@toeverything/components/ui';
+import { useRef, type ComponentType } from 'react';
import { copy } from './copy';
const IconBooth = ({
diff --git a/apps/ligo-virgo/src/pages/tools/index.tsx b/apps/ligo-virgo/src/pages/tools/index.tsx
index 984fae407b..ff32a85cff 100644
--- a/apps/ligo-virgo/src/pages/tools/index.tsx
+++ b/apps/ligo-virgo/src/pages/tools/index.tsx
@@ -1,4 +1,4 @@
-import { Routes, Route } from 'react-router-dom';
+import { Route, Routes } from 'react-router-dom';
import { Container } from './container';
import { Icons } from './icons';
diff --git a/apps/ligo-virgo/src/pages/ui/index.tsx b/apps/ligo-virgo/src/pages/ui/index.tsx
index be4d79a688..48189656eb 100644
--- a/apps/ligo-virgo/src/pages/ui/index.tsx
+++ b/apps/ligo-virgo/src/pages/ui/index.tsx
@@ -1,5 +1,3 @@
-import React from 'react';
-
export const UIPage = () => {
return (
diff --git a/apps/ligo-virgo/src/pages/workspace/Whiteboard.tsx b/apps/ligo-virgo/src/pages/workspace/Edgeless.tsx
similarity index 92%
rename from apps/ligo-virgo/src/pages/workspace/Whiteboard.tsx
rename to apps/ligo-virgo/src/pages/workspace/Edgeless.tsx
index 16bdf814fe..c84ceda481 100644
--- a/apps/ligo-virgo/src/pages/workspace/Whiteboard.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/Edgeless.tsx
@@ -2,18 +2,18 @@ import { memo, useEffect } from 'react';
import { useParams } from 'react-router';
import { AffineBoard } from '@toeverything/components/affine-board';
-import { useUserAndSpaces } from '@toeverything/datasource/state';
import { services } from '@toeverything/datasource/db-service';
+import { useUserAndSpaces } from '@toeverything/datasource/state';
const MemoAffineBoard = memo(AffineBoard, (prev, next) => {
return prev.rootBlockId === next.rootBlockId;
});
-type WhiteboardProps = {
+type EdgelessProps = {
workspace: string;
};
-export const Whiteboard = (props: WhiteboardProps) => {
+export const Edgeless = (props: EdgelessProps) => {
const { page_id } = useParams();
const { user } = useUserAndSpaces();
diff --git a/apps/ligo-virgo/src/pages/workspace/Home.tsx b/apps/ligo-virgo/src/pages/workspace/Home.tsx
index 0077fa69be..d0ac1f3872 100644
--- a/apps/ligo-virgo/src/pages/workspace/Home.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/Home.tsx
@@ -1,7 +1,7 @@
+import { services, TemplateFactory } from '@toeverything/datasource/db-service';
+import { useUserAndSpaces } from '@toeverything/datasource/state';
import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
-import { useUserAndSpaces } from '@toeverything/datasource/state';
-import { services, TemplateFactory } from '@toeverything/datasource/db-service';
export function WorkspaceHome() {
const navigate = useNavigate();
@@ -22,8 +22,12 @@ export function WorkspaceHome() {
workspace_id,
user_initial_page_id,
TemplateFactory.generatePageTemplateByGroupKeys({
- name: '👋 Get Started with AFFINE',
- groupKeys: ['getStartedGroup0', 'getStartedGroup1'],
+ name: '👋 Get Started with AFFiNE',
+ groupKeys: [
+ 'getStartedGroup0',
+ 'getStartedGroup1',
+ 'getStartedGroup2',
+ ],
})
);
}
diff --git a/apps/ligo-virgo/src/pages/workspace/WorkspaceContainer.tsx b/apps/ligo-virgo/src/pages/workspace/WorkspaceContainer.tsx
index a2e5c92970..8e83c601a0 100644
--- a/apps/ligo-virgo/src/pages/workspace/WorkspaceContainer.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/WorkspaceContainer.tsx
@@ -1,14 +1,13 @@
-/* eslint-disable filename-rules/match */
-import { Routes, Route, useParams, Navigate } from 'react-router';
+import { Route, Routes, useParams } from 'react-router';
import { useUserAndSpaces } from '@toeverything/datasource/state';
import { WorkspaceRootContainer } from './Container';
import { Page } from './docs';
+import { Edgeless } from './Edgeless';
import { WorkspaceHome } from './Home';
import Labels from './labels';
import Pages from './pages';
-import { Whiteboard } from './Whiteboard';
export function WorkspaceContainer() {
const { workspace_id } = useParams();
@@ -27,8 +26,8 @@ export function WorkspaceContainer() {
} />
} />
}
+ path="/:page_id/edgeless"
+ element={
}
/>
{
return {
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/index.spec.tsx b/apps/ligo-virgo/src/pages/workspace/docs/index.spec.tsx
index e17c51392b..6e1b4880ff 100644
--- a/apps/ligo-virgo/src/pages/workspace/docs/index.spec.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/docs/index.spec.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable filename-rules/match */
import { render } from '@testing-library/react';
import { Page } from './index';
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx b/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx
index 6769ed2889..b46eea5215 100644
--- a/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx
@@ -1,17 +1,17 @@
-import { styled, Input } from '@toeverything/components/ui';
import { PinIcon } from '@toeverything/components/icons';
+import { Input, styled } from '@toeverything/components/ui';
+import { services } from '@toeverything/datasource/db-service';
import {
- useUserAndSpaces,
useShowSpaceSidebar,
+ useUserAndSpaces,
} from '@toeverything/datasource/state';
-import React, {
+import {
ChangeEvent,
KeyboardEvent,
useCallback,
useEffect,
useState,
} from 'react';
-import { services } from '@toeverything/datasource/db-service';
import { Logo } from './components/logo/Logo';
const WorkspaceContainer = styled('div')({
diff --git a/apps/ligo-virgo/webpack.config.js b/apps/ligo-virgo/webpack.config.js
index 2082de5348..4bf721409c 100644
--- a/apps/ligo-virgo/webpack.config.js
+++ b/apps/ligo-virgo/webpack.config.js
@@ -73,9 +73,9 @@ module.exports = function (webpackConfig) {
priority: -5,
chunks: 'all',
},
- whiteboard: {
+ edgeless: {
test: /(libs\/components\/board-|[\\/]node_modules[\\/]@tldraw)/,
- name: 'whiteboard',
+ name: 'edgeless',
priority: -7,
chunks: 'all',
},
diff --git a/apps/venus/package.json b/apps/venus/package.json
index fe69da1b8e..321da2b80d 100644
--- a/apps/venus/package.json
+++ b/apps/venus/package.json
@@ -7,16 +7,18 @@
"keywords": [],
"author": "DarkSky ",
"dependencies": {
- "@mui/joy": "^5.0.0-alpha.39",
"@emotion/react": "^11.10.0",
"@emotion/styled": "^11.10.0",
- "lozad": "^1.16.0"
+ "@mui/joy": "^5.0.0-alpha.39",
+ "i18next": "^21.9.1",
+ "lozad": "^1.16.0",
+ "react-i18next": "^11.18.4"
},
"devDependencies": {
- "mini-css-extract-plugin": "^2.6.1",
"image-minimizer-webpack-plugin": "^3.2.3",
"imagemin": "^8.0.1",
"imagemin-optipng": "^8.0.0",
+ "mini-css-extract-plugin": "^2.6.1",
"webpack": "^5.74.0"
}
}
diff --git a/apps/venus/src/app/i18n/index.ts b/apps/venus/src/app/i18n/index.ts
new file mode 100644
index 0000000000..9ddaa8330d
--- /dev/null
+++ b/apps/venus/src/app/i18n/index.ts
@@ -0,0 +1,25 @@
+import i18next from 'i18next';
+import { initReactI18next } from 'react-i18next';
+import en_US from './resources/en.json';
+import zh_CN from './resources/zh.json';
+
+const resources = {
+ en: en_US,
+ zh: zh_CN,
+} as const;
+
+i18next.use(initReactI18next).init({
+ lng: 'en',
+ fallbackLng: 'en',
+ resources,
+ interpolation: {
+ escapeValue: false, // not needed for react as it escapes by default
+ },
+});
+
+export const options = [
+ { value: 'en', text: 'English' },
+ { value: 'zh', text: '简体中文' },
+];
+
+export { i18next };
diff --git a/apps/venus/src/app/i18n/resources/en.json b/apps/venus/src/app/i18n/resources/en.json
new file mode 100644
index 0000000000..cd7a377352
--- /dev/null
+++ b/apps/venus/src/app/i18n/resources/en.json
@@ -0,0 +1,34 @@
+{
+ "translation": {
+ "Open Source": "Open Source",
+ "Privacy First": "Privacy First",
+ "Alternative": "Alternative",
+ "Check GitHub": "Check GitHub",
+ "Try it Online": "Try it Online",
+ "description1": {
+ "part1": "Affine is the next-generation collaborative knowledge base for professionals.",
+ "part2": "It's not just a collection of Docs, whiteboard, and tables.",
+ "part3": "Transform any building block as you like.",
+ "part4": "Say goodbye to redundancy. Store your data once, and keep your data as you like it."
+ },
+ "description2": {
+ "part1": "Shape Your Page",
+ "part2": "Docs, Kanbans, and Databases are all fully functional anywhere, anytime. A truly what-you-see-is-what-you-get environment for your data.",
+ "part3": "All pages come with a document (Paper Mode) and whiteboard (Edgeless Mode) view."
+ },
+ "description3": {
+ "part1": "Plan Your Task",
+ "part2": "No more chaos managing multiple views.",
+ "part3": "Set a TODO with Markdown, and seamlessly edit it within a Kanban.",
+ "part4": "Managing multi-dimensional tables should be this simple - and now it is."
+ },
+ "description4": {
+ "part1": "Privacy-first, and collaborative. No compromises whatsoever.",
+ "part2": "We don't like being locked-in, and neither should you. Privacy is at the foundation of everything we do, but it should not limit us that's why there are no compromises.",
+ "part3": "Your data is yours;it is always locally stored and secured - available to you always. While still being able to enjoy collaboration features such as real-time editing and sharing with others, without any cloud setup."
+ },
+ "BuildFor": "Build for an open and semantic future",
+ "KeepUpdated": "Keep Updated on",
+ "Join": "Join Our Community"
+ }
+}
diff --git a/apps/venus/src/app/i18n/resources/zh.json b/apps/venus/src/app/i18n/resources/zh.json
new file mode 100644
index 0000000000..eb4cf432dd
--- /dev/null
+++ b/apps/venus/src/app/i18n/resources/zh.json
@@ -0,0 +1,34 @@
+{
+ "translation": {
+ "Open Source": "开源",
+ "Privacy First": "隐私第一",
+ "Alternative": "的另一种选择",
+ "Check GitHub": "GitHub中查看",
+ "Try it Online": "在线上试试",
+ "description1": {
+ "part1": "Affine是面向专业人士的下一代协同知识库",
+ "part2": "它不仅仅是一个文档、白板和表格的集合。",
+ "part3": "可以根据需要转换任何构建块。",
+ "part4": "向冗余说再见吧。将数据存储一次,并保留您喜欢的数据。"
+ },
+ "description2": {
+ "part1": "塑造您的页面",
+ "part2": "文档、看板和数据库在任何地方、任何时候都是完全可用的,一个真正的“所见即所得”的数据环境。",
+ "part3": "所有页面都有一个文档(纸张模式)和白板(无边缘模式)视图。"
+ },
+ "description3": {
+ "part1": "计划您的任务",
+ "part2": "不再混乱地管理多个视图。",
+ "part3": "使用 Markdown 设置 TODO,并在看板中无缝地编辑它。",
+ "part4": "管理多维表格本应该就这么简单——现在的它就是这么简单。"
+ },
+ "description4": {
+ "part1": "隐私第一,合作无间,绝不妥协。",
+ "part2": "我们不喜欢被关起来,您也不应该。隐私是我们做任何事情的基础,但它不应该限制我们,这就是为什么我们决不妥协。",
+ "part3": "您的数据是您自己的,它总是安全的在本地存储并随时供您使用。您不需要任何云设置就可以享受协作功能,即时编辑和与他人共享。"
+ },
+ "BuildFor": "构建一个开放和语义化的未来",
+ "KeepUpdated": "持续更新在",
+ "Join": "加入我们的社区"
+ }
+}
diff --git a/apps/venus/src/app/index.tsx b/apps/venus/src/app/index.tsx
index cd95682389..e4d9c7854e 100644
--- a/apps/venus/src/app/index.tsx
+++ b/apps/venus/src/app/index.tsx
@@ -1,20 +1,22 @@
/* eslint-disable max-lines */
/* eslint-disable @typescript-eslint/naming-convention */
-/* eslint-disable filename-rules/match */
-import { useEffect, useMemo, useState } from 'react';
import clsx from 'clsx';
+import { useEffect, useMemo, useState } from 'react';
-import { CssVarsProvider, styled } from '@mui/joy/styles';
-import { Box, Button, Container, Grid, SvgIcon, Typography } from '@mui/joy';
import GitHubIcon from '@mui/icons-material/GitHub';
import RedditIcon from '@mui/icons-material/Reddit';
import TelegramIcon from '@mui/icons-material/Telegram';
+import { Box, Button, Container, Grid, SvgIcon, Typography } from '@mui/joy';
+import Option from '@mui/joy/Option';
+import Select from '@mui/joy/Select';
+import { CssVarsProvider, styled } from '@mui/joy/styles';
import { LogoIcon } from '@toeverything/components/icons';
// eslint-disable-next-line no-restricted-imports
import { useMediaQuery } from '@mui/material';
-
-import LogoImage from './logo.png';
+import { useTranslation } from 'react-i18next';
import CollaborationImage from './collaboration.png';
+import { options } from './i18n';
+import LogoImage from './logo.png';
import PageImage from './page.png';
import ShapeImage from './shape.png';
import TaskImage from './task.png';
@@ -200,6 +202,7 @@ const AffineImage = styled('img')({
const GitHub = (props: { center?: boolean; flat?: boolean }) => {
const matches = useMediaQuery('(max-width: 1024px)');
+ const { t } = useTranslation();
return (
{
startIcon={ }
size="lg"
>
- {props.center ? 'Check ' : ''}GitHub
+ {props.center ? t('Check GitHub') : t('GitHub')}
);
};
const AFFiNEOnline = (props: { center?: boolean; flat?: boolean }) => {
const matches = useMediaQuery('(max-width: 1024px)');
-
+ const { t } = useTranslation();
return (
{
@@ -278,14 +281,18 @@ const AFFiNEOnline = (props: { center?: boolean; flat?: boolean }) => {
startIcon={ }
size="lg"
>
- Try it Online
+ {t('Try it Online')}
);
};
export function App() {
const matches = useMediaQuery('(max-width: 1024px)');
+ const { t, i18n } = useTranslation();
+ const changeLanguage = (event: any) => {
+ i18n.changeLanguage(event);
+ };
return (
Blog
+
+ {options.map(option => (
+
+ {option.text}
+
+ ))}
+
- Open Source,
+ {t('Open Source')},
- Privacy First
+ {t('Privacy First')}
@@ -414,7 +428,7 @@ export function App() {
},
}}
>
- Alternative
+ {t('Alternative')}
@@ -433,8 +447,7 @@ export function App() {
fontWeight={'400'}
sx={{ color: '#888' }}
>
- Affine is the next-generation collaborative
- knowledge base for professionals.
+ {t('description1.part1')}
@@ -489,8 +502,7 @@ export function App() {
level={matches ? 'h2' : 'h1'}
fontWeight={'bold'}
>
- It’s not just a collection of Docs, whiteboard, and
- tables.
+ {t('description1.part2')}
@@ -507,11 +519,10 @@ export function App() {
}}
>
- Transform any building block as you like.
+ {t('description1.part3')}
- Say goodbye to redundancy. Store your data once, and
- keep your data as you like it.
+ {t('description1.part4')}
@@ -548,23 +559,19 @@ export function App() {
fontWeight={'bold'}
style={{ marginBottom: '0.5em' }}
>
- Shape Your Page
+ {t('description2.part1')}
- Docs, Kanbans, and Databases are all fully
- functional anywhere, anytime. A truly
- what-you-see-is-what-you-get environment for
- your data.
+ {t('description2.part2')}
- All pages come with a document (Paper Mode) and
- whiteboard (Edgeless Mode) view.
+ {t('description2.part3')}
@@ -626,27 +633,25 @@ export function App() {
fontWeight={'bold'}
style={{ marginBottom: '0.5em' }}
>
- Plan Your Task
+ {t('description3.part1')}
- No more chaos managing multiple views.
+ {t('description3.part2')}
- Set a TODO with Markdown, and seamlessly edit it
- within a Kanban.
+ {t('description3.part3')}
- Managing multi-dimensional tables should be this
- simple – and now it is.
+ {t('description3.part4')}
@@ -698,27 +703,19 @@ export function App() {
fontWeight={'bold'}
style={{ marginBottom: '0.5em' }}
>
- Privacy-first, and collaborative. No compromises
- whatsoever.
+ {t('description4.part1')}
- We don’t like being locked-in, and neither should
- you. Privacy is at the foundation of everything we
- do, but it should not limit us that’s+ why there are
- no compromises.
+ {t('description4.part2')}
- Your data is yours; it is always locally stored and
- secured - available to you always. While still being
- able enjoy collaboration features such as real-time
- editing and sharing with others, without any cloud
- setup.
+ {t('description4.part3')}
@@ -763,7 +760,7 @@ export function App() {
}}
>
- Build for an open and semantic future
+ {t('BuildFor')}
@@ -779,7 +776,7 @@ export function App() {
>
- Keep Updated on
+ {t('KeepUpdated')}
@@ -796,7 +793,7 @@ export function App() {
}}
>
- Join Our Community
+ {t('Join')}
diff --git a/apps/venus/src/index.tsx b/apps/venus/src/index.tsx
index c14c54bfa5..5fdc926e59 100644
--- a/apps/venus/src/index.tsx
+++ b/apps/venus/src/index.tsx
@@ -1,7 +1,7 @@
-/* eslint-disable filename-rules/match */
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
+import './app/i18n';
import App from './app';
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
deleted file mode 100644
index dbf6928456..0000000000
--- a/docs/CONTRIBUTING.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# AFFiNE CONTRIBUTING
-
-Contributions are **welcome** and will be fully **credited**.
-
-## **Requirements**
-
-If the project maintainer has any additional requirements, you will find them listed here.
-
-- Code Style [AFFiNE Code Guideline](./affine-code-guideline.md)
-- Git Rules [AFFiNE Git Guideline ](./affine-git-guideline.md)
-- • **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
-
-**Happy coding**!
diff --git a/docs/affine-code-guideline.md b/docs/affine-code-guideline.md
deleted file mode 100644
index d98ba3cb51..0000000000
--- a/docs/affine-code-guideline.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# AFFiNE Code Guideline
-
-| Item | Specification | Example |
-| ----------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------- |
-| [Packages/Paths]() | aaa-bbb-ccc | ligo-virgo, editor-todo |
-| [.tsx]() | PascalCase | AddPage.tsx |
-| [.ts]() | kebab-case | file-export.ts |
-| [.json]() | kebab-case | file-export.ts |
-| [Domain File]() | OpenRules | xx._d.ts_ | _tsconfig.xx_.json | xx.spec .ts | .env.xx | yy-ds.ts |
-| [Types]() | UpperCamelCase | WebEvent |
-| [Enum variants]() | UpperCamelCase | Status{ Todo,Completed } |
-| [Functions]() | lowerCamelCase | |
-| [React Funciton Compoment]() | UpperCamelCase | function DocShare(){} |
-| [React HOC]() | UpperCamelCase | function BussinessText(){} |
-| [Function Parameter]() | lowerCamelCase | function searchByIdOrName(idOrname){ } |
-| [Methods for external access]() | lowerCamelCase | public sayHello(){ }; |
-| [Externally Accessible Variables (Variables)]() | lowerCamelCase | animal.sleepCount |
-| [General constructors]() | constructor or with_more_details | |
-| [Local variables]() | lowerCamelCase | const tableCollection = []; |
-| [Statics]() | SCREAMING_SNAKE_CASE | GLOBAL_MESSAGES |
-| [Constants](b) | SCREAMING_SNAKE_CASE | GLOBAL_CONFIG |
-| [Type parameters]() | UpperCamelCase , usually a single capital letter: T | let a: Animal = new Animal() |
diff --git a/docs/affine-git-guideline.md b/docs/affine-git-guideline.md
deleted file mode 100644
index 71fcb12834..0000000000
--- a/docs/affine-git-guideline.md
+++ /dev/null
@@ -1,91 +0,0 @@
-# AFFiNE Git Guideline
-
-# 1. Git Branch Name
-
-- fix/
-- feat/
-
-# 2. **Commit message guidelines**
-
-AFFiNE uses [semantic-release](https://github.com/semantic-release/semantic-release) for automated version management and package publishing. For that to work, commitmessages need to be in the right format.
-
-### **Atomic commits**
-
-If possible, make [atomic commits](https://en.wikipedia.org/wiki/Atomic_commit), which means:
-
-- a commit should contain exactly one self-contained functional change
-- a functional change should be contained in exactly one commit
-- a commit should not create an inconsistent state (such as test errors, linting errors, partial fix, feature with documentation etc...)
-
-A complex feature can be broken down into multiple commits as long as each one keep a consistent state and consist of a self-contained change.
-
-### **Commit message format**
-
-Each commit message consists of a **header**, a **body** and a **footer**. The header has a special format that includes a **type**, a **scope** and a **subject**:
-
-`():
-
-
-
-
-`
-
-The **header** is mandatory and the **scope** of the header is optional.
-
-The **footer** can contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages).
-
-### **Revert**
-
-If the commit reverts a previous commit, it should begin with `revert:` , followed by the header of the reverted commit. In the body it should say: `This reverts commit .`, where the hash is the SHA of the commit being reverted.
-
-### **Type**
-
-The type must be one of the following:
-| Type | Description |
-| ----------- | ----------- |
-| build | Changes that affect the build system or external | dependencies (example scopes: gulp, broccoli, npm) |
-| ci | Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) |
-| docs | Documentation only changes |
-| feat | A new feature |
-| fix | A bug fix |
-| perf | A code change that improves performance |
-| refactor | A code change that neither fixes a bug nor adds a feature |
-| style | Changes that do not affect the meaning of the code(white-space, formatting, missing semi-colons, etc) |
-| test | Adding missing tests or correcting existing tests |
-| chore | Changes to the build process or auxiliary tools | |
-
-### **Subject**
-
-The subject contains succinct description of the change:
-
-- use the imperative, present tense: "change" not "changed" nor "changes"
-- don't capitalize first letter
-- no dot (.) at the end
-
-### **Body**
-
-Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior.
-
-### **Footer**
-
-The footer should contain any information about **Breaking Changes** and is also the place to reference GitHub issues that this commit **Closes**.
-
-**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
-
-### **Examples**
-
-`fix(pencil): stop graphite breaking when too much pressure applied`
-
-``feat(pencil): add 'graphiteWidth' option`
-
-Fix #42`
-
-`perf(pencil): remove graphiteWidth option`
-
-BREAKING CHANGE: The graphiteWidth option has been removed.
-
-The default graphite width of 10mm is always used for performance reasons.`
-
-# 3. tracking-your-work-with-issues
-
-[https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues)
diff --git a/docs/affine-icons-user-guide.md b/docs/affine-icons-user-guide.md
deleted file mode 100644
index 0e376a4099..0000000000
--- a/docs/affine-icons-user-guide.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## AFFiNE Icons
-
-> Abundant and colorful icon resource for free free use
-
-Website: [http://localhost:4200/tools/icons](http://localhost:4200/tools/icons)
-
-Figma: [Figma AFFiNE Icons](https://www.figma.com/file/7pyx5gMz6CN0qSRADmScQ7/AFFINE?node-id=665%3A1734)
diff --git a/docs/how-to-add-ui-component-in-affine.md b/docs/how-to-add-ui-component-in-affine.md
deleted file mode 100644
index acb2a80911..0000000000
--- a/docs/how-to-add-ui-component-in-affine.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Tutorial
-
-AFFiNE defines a new component development specification in Figma, extends AFFiNE UI Components based on MUI BASE and MUI SYSTEM, and supplements as needed https://github.com/toeverything/AFFiNE/tree/master/libs/components/ui , eg `src/libs/components/ui/src/button/base-button.ts`
-
-```jsx
-import ButtonUnstyled, {
- buttonUnstyledClasses,
-} from '@mui/base/ButtonUnstyled';
-import { styled } from '../styled';
-
-/* eslint-disable @typescript-eslint/naming-convention */
-const blue = {
- 500: '#007FFF',
- 600: '#0072E5',
- 700: '#0059B2',
-};
-/* eslint-enable @typescript-eslint/naming-convention */
-
-export const BaseButton = styled(ButtonUnstyled)`
- font-family: IBM Plex Sans, sans-serif;
- font-weight: bold;
- font-size: 0.875rem;
- background-color: ${blue[500]};
- border-radius: 8px;
- padding: 4px 8px;
- color: white;
- transition: all 150ms ease;
- cursor: pointer;
- border: none;
-
- &:hover {
- background-color: ${blue[600]};
- }
-
- &.${buttonUnstyledClasses.active} {
- background-color: ${blue[700]};
- }
-
- &.${buttonUnstyledClasses.focusVisible} {
- box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 5px rgba(0, 127, 255, 0.5);
- outline: none;
- }
-
- &.${buttonUnstyledClasses.disabled} {
- opacity: 0.5;
- cursor: not-allowed;
- }
-`;
-```
-
-```jsx
-export { BaseButton } from './base-button';
-```
diff --git a/docs/how-to-auto-download-figma-assets-in-affine.md b/docs/how-to-auto-download-figma-assets-in-affine.md
deleted file mode 100644
index be0794b667..0000000000
--- a/docs/how-to-auto-download-figma-assets-in-affine.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Create or edit the `.env.local` file in the project root directory, add `FIGMA_TOKEN`, you can refer to Generate ACCESS_TOKEN: https://www.figma.com/developers/api#access-tokens
-
-```
-FIGMA_TOKEN=your-figma-token
-```
-
-Execute the command `nx run components-icons:figmaRes` to synchronize figma resources
-
-figma icon resource address: https://www.figma.com/file/7pyx5gMz6CN0qSRADmScQ7/AFFINE?node-id=665%3A1734
-
-### Icon Supplementary Style
-
-Some icons downloaded directly have incorrect styles. You can add supplementary styles in `tools/executors/figmaRes/patch-styles.js`. The key is the name of the icon kebab-case.
diff --git a/docs/how-to-customize-rollup-config.md b/docs/how-to-customize-rollup-config.md
deleted file mode 100644
index f9362afb60..0000000000
--- a/docs/how-to-customize-rollup-config.md
+++ /dev/null
@@ -1,3 +0,0 @@
-## Single Component Rollup Config
-
-If styles are used in a Component, `rollupConfig` under `project.json` needs to be modified to `libs/rollup.config.cjs`
diff --git a/docs/how-to-write-css-in-affine.md b/docs/how-to-write-css-in-affine.md
deleted file mode 100644
index bf84ef99c4..0000000000
--- a/docs/how-to-write-css-in-affine.md
+++ /dev/null
@@ -1,103 +0,0 @@
-[toc]
-
-# Tutorial
-
-1. MUI styled
-
-```jsx
-import type { MouseEventHandler, ReactNode } from 'react';
-import { styled } from '@toeverything/components/ui';
-
-const CardContainer = styled('div')({
- display: 'flex',
- flexDirection: 'column',
- backgroundColor: '#fff',
- border: '1px solid #E2E7ED',
- borderRadius: '5px',
-});
-
-const CardContent = styled('div')({
- margin: '23px 52px 24px 19px',
-});
-
-const CardActions = styled('div')({
- cursor: 'pointer',
- display: 'flex',
- alignItems: 'center',
- width: '100%',
- height: '29px',
- background: 'rgba(152, 172, 189, 0.1)',
- borderRadius: '0px 0px 5px 5px',
- padding: '6px 0 6px 19px',
- fontSize: '12px',
- fontWeight: '300',
- color: '#98ACBD',
-});
-
-const PlusIcon = styled('div')({
- marginRight: '9px',
- fontWeight: '500',
- lineHeight: 0,
- '::before': {
- content: '"+"',
- },
-});
-
-export const Card = ({
- children,
- onAddItem,
-}: {
- children?: ReactNode,
- onAddItem?: MouseEventHandler,
-}) => {
- return (
-
- {children}
-
-
- Add item
-
-
- );
-};
-```
-
-## 2. import `*.scss`
-
-```jsx
-import styles from './tree-item.module.scss';
-
-export const TreeItem = forwardRef(
- () => {
-
- return (
-
-
-
- );
- }
-);
-
-
-```
-
-## 3. import `*.css`,
-
-```js
-import 'codemirror/lib/codemirror.css';
-import 'codemirror/lib/codemirror';
-```
diff --git a/libs/components/account/src/error.tsx b/libs/components/account/src/error.tsx
index 6159016323..fb1f93f551 100644
--- a/libs/components/account/src/error.tsx
+++ b/libs/components/account/src/error.tsx
@@ -1,10 +1,7 @@
-import { Link } from 'react-router-dom';
import style9 from 'style9';
-import { getAuth, signOut } from 'firebase/auth';
-import { MuiBox as Box } from '@toeverything/components/ui';
import { keyframes } from '@emotion/react';
-import { LOGOUT_LOCAL_STORAGE, LOGOUT_COOKIES } from '@toeverything/utils';
+import { MuiBox as Box } from '@toeverything/components/ui';
const styles = style9.create({
container: {
diff --git a/libs/components/account/src/index.ts b/libs/components/account/src/index.ts
index 5a69b2964e..8610c4e1bf 100644
--- a/libs/components/account/src/index.ts
+++ b/libs/components/account/src/index.ts
@@ -1,3 +1,3 @@
-export { Login } from './login';
export { Error } from './error';
export { PageLoading } from './loading';
+export { Login } from './login';
diff --git a/libs/components/account/src/loading.tsx b/libs/components/account/src/loading.tsx
index 095d82d9dd..b7bcb4ad49 100644
--- a/libs/components/account/src/loading.tsx
+++ b/libs/components/account/src/loading.tsx
@@ -1,5 +1,5 @@
-import style9 from 'style9';
import { MuiCircularProgress as CircularProgress } from '@toeverything/components/ui';
+import style9 from 'style9';
const styles = style9.create({
container: {
diff --git a/libs/components/account/src/login/fs.tsx b/libs/components/account/src/login/FileSystem.tsx
similarity index 96%
rename from libs/components/account/src/login/fs.tsx
rename to libs/components/account/src/login/FileSystem.tsx
index 2482e5187c..8b70bc51e3 100644
--- a/libs/components/account/src/login/fs.tsx
+++ b/libs/components/account/src/login/FileSystem.tsx
@@ -1,5 +1,4 @@
-/* eslint-disable filename-rules/match */
-import { useEffect, useMemo } from 'react';
+import { useMemo } from 'react';
import { LogoIcon } from '@toeverything/components/icons';
import { MuiButton } from '@toeverything/components/ui';
diff --git a/libs/components/account/src/login/firebase.tsx b/libs/components/account/src/login/Firebase.tsx
similarity index 99%
rename from libs/components/account/src/login/firebase.tsx
rename to libs/components/account/src/login/Firebase.tsx
index 0c295010e7..f976ef8a84 100644
--- a/libs/components/account/src/login/firebase.tsx
+++ b/libs/components/account/src/login/Firebase.tsx
@@ -1,12 +1,11 @@
-/* eslint-disable filename-rules/match */
-import { useCallback, useMemo } from 'react';
import { initializeApp } from 'firebase/app';
import {
- GoogleAuthProvider,
- getAuth,
- signInWithPopup,
browserLocalPersistence,
+ getAuth,
+ GoogleAuthProvider,
+ signInWithPopup,
} from 'firebase/auth';
+import { useCallback, useMemo } from 'react';
import { MuiButton } from '@toeverything/components/ui';
diff --git a/libs/components/account/src/login/authing.tsx b/libs/components/account/src/login/authing.tsx
deleted file mode 100644
index e4a1b01ce9..0000000000
--- a/libs/components/account/src/login/authing.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import { useCallback, useEffect, useMemo } from 'react';
-import { useNavigate } from 'react-router-dom';
-import style9 from 'style9';
-import { MuiBox as Box } from '@toeverything/components/ui';
-import { Guard as AuthingGuard } from '@authing/react-ui-components';
-import type { User as AuthingUser } from 'authing-js-sdk';
-
-import {
- AUTHING_APP_ID_US,
- AUTHING_APP_ID_CN,
- AUTHING_APP_HOST_US,
-} from '@toeverything/utils';
-import { useUserAndSpaces } from '@toeverything/datasource/state';
-
-import '@authing/react-ui-components/lib/index.min.css';
-
-export function Authing() {
- const navigate = useNavigate();
- const { handleUserLoginSuccess, currentSpaceId } = useUserAndSpaces();
-
- /**
- * Refer to Authing documentation https://docs.authing.cn/v2/reference/guard/react.html
- */
- const handle_login_success = useCallback(
- async (authingUser: AuthingUser) => {
- handleUserLoginSuccess(authingUser);
- },
- [handleUserLoginSuccess]
- );
-
- const authing_config = useMemo(() => {
- return {
- host: AUTHING_APP_HOST_US,
- };
- }, []);
-
- useEffect(() => {
- if (currentSpaceId) {
- const targetRoute = `/${currentSpaceId}`;
- navigate(targetRoute);
- }
- }, [currentSpaceId, navigate]);
-
- return (
-
- );
-}
-
-const styles = style9.create({
- loginContainer: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- width: '100%',
- height: 'calc( 100vh - 64px )',
- },
-});
diff --git a/libs/components/account/src/login/index.tsx b/libs/components/account/src/login/index.tsx
index e0dbed46b0..5c80f37125 100644
--- a/libs/components/account/src/login/index.tsx
+++ b/libs/components/account/src/login/index.tsx
@@ -1,12 +1,11 @@
-/* eslint-disable filename-rules/match */
-import { useCallback, useState } from 'react';
import { LogoImg } from '@toeverything/components/common';
import { MuiBox, MuiGrid, MuiSnackbar } from '@toeverything/components/ui';
+import { useCallback, useState } from 'react';
-// import { Authing } from './authing';
-import { Firebase } from './firebase';
-import { FileSystem } from './fs';
import { Error } from './../error';
+// import { Authing } from './Authing';
+import { FileSystem } from './FileSystem';
+import { Firebase } from './Firebase';
export function Login() {
const [error, setError] = useState(false);
diff --git a/libs/components/affine-board/src/Board.tsx b/libs/components/affine-board/src/Board.tsx
index 262d960828..af9e8982fe 100644
--- a/libs/components/affine-board/src/Board.tsx
+++ b/libs/components/affine-board/src/Board.tsx
@@ -1,24 +1,30 @@
-import { useEffect, useState } from 'react';
-import { Tldraw } from '@toeverything/components/board-draw';
-import { tools } from '@toeverything/components/board-tools';
-import { getSession } from '@toeverything/components/board-sessions';
-import * as commands from '@toeverything/components/board-commands';
-import { TldrawApp, deepCopy } from '@toeverything/components/board-state';
-import { TDShapeType } from '@toeverything/components/board-types';
-import { services } from '@toeverything/datasource/db-service';
-import { useShapes } from './hooks';
-import { RecastBlockProvider } from '@toeverything/components/editor-core';
import { createEditor } from '@toeverything/components/affine-editor';
+import * as commands from '@toeverything/components/board-commands';
+import { Tldraw } from '@toeverything/components/board-draw';
+import { getSession } from '@toeverything/components/board-sessions';
+import { deepCopy, TldrawApp } from '@toeverything/components/board-state';
+import { tools } from '@toeverything/components/board-tools';
+import { TDShapeType } from '@toeverything/components/board-types';
+import {
+ getClipDataOfBlocksById,
+ RecastBlockProvider,
+} from '@toeverything/components/editor-core';
+import { services } from '@toeverything/datasource/db-service';
import { AsyncBlock, BlockEditor } from '@toeverything/framework/virgo';
+import { useEffect, useState } from 'react';
+import { useShapes } from './hooks';
interface AffineBoardProps {
workspace: string;
rootBlockId: string;
}
-const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
+const AffineBoard = ({
+ workspace,
+ rootBlockId,
+ editor,
+}: AffineBoardProps & { editor: BlockEditor }) => {
const [app, set_app] = useState();
-
const [document] = useState(() => {
return {
...deepCopy(TldrawApp.default_document),
@@ -45,10 +51,10 @@ const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
};
});
- const shapes = useShapes(workspace, rootBlockId);
+ const { shapes, bindings } = useShapes(workspace, rootBlockId);
useEffect(() => {
if (app) {
- app.replacePageContent(shapes || {}, {}, {});
+ app.replacePageContent(shapes || {}, bindings, {});
}
}, [app, shapes]);
@@ -62,7 +68,19 @@ const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
onMount(app) {
set_app(app);
},
- onChangePage(app, shapes, bindings, assets) {
+
+ async onCopy(e, groupIds) {
+ const clip = await getClipDataOfBlocksById(
+ editor,
+ groupIds
+ );
+
+ e.clipboardData?.setData(
+ clip.getMimeType(),
+ clip.getData()
+ );
+ },
+ async onChangePage(app, shapes, bindings, assets) {
Promise.all(
Object.entries(shapes).map(async ([id, shape]) => {
if (shape === undefined) {
@@ -91,7 +109,20 @@ const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
});
}
shape.affineId = block.id;
- return services.api.editorBlock.update({
+
+ Object.keys(bindings).forEach(bilingKey => {
+ if (
+ bindings[bilingKey]?.fromId === shape.id
+ ) {
+ bindings[bilingKey].fromId = block.id;
+ }
+ if (
+ bindings[bilingKey]?.toId === shape.id
+ ) {
+ bindings[bilingKey].toId = block.id;
+ }
+ });
+ return await services.api.editorBlock.update({
workspace: shape.workspace,
id: block.id,
properties: {
@@ -103,6 +134,32 @@ const AffineBoard = ({ workspace, rootBlockId }: AffineBoardProps) => {
}
})
);
+ let pageBindingsString = (
+ await services.api.editorBlock.get({
+ workspace: workspace,
+ ids: [rootBlockId],
+ })
+ )?.[0].properties.bindings?.value;
+ console.log(123123123);
+ let pageBindings = JSON.parse(pageBindingsString ?? '{}');
+ console.log(pageBindings, 3333, bindings);
+ Object.keys(bindings).forEach(bindingsKey => {
+ console.log(345345345345345);
+ if (!bindings[bindingsKey]) {
+ delete pageBindings[bindingsKey];
+ } else {
+ Object.assign(pageBindings, bindings);
+ }
+ });
+ services.api.editorBlock.update({
+ workspace: workspace,
+ id: rootBlockId,
+ properties: {
+ bindings: {
+ value: JSON.stringify(pageBindings),
+ },
+ },
+ });
},
}}
/>
@@ -130,7 +187,11 @@ export const AffineBoardWitchContext = ({
}, [editor, rootBlockId]);
return page ? (
-
+
) : null;
};
diff --git a/libs/components/affine-board/src/hooks/use-shapes.ts b/libs/components/affine-board/src/hooks/use-shapes.ts
index ecff1b8431..beb8c50efa 100644
--- a/libs/components/affine-board/src/hooks/use-shapes.ts
+++ b/libs/components/affine-board/src/hooks/use-shapes.ts
@@ -1,36 +1,60 @@
-import { useEffect, useState } from 'react';
-import { services } from '@toeverything/datasource/db-service';
-import type { ReturnEditorBlock } from '@toeverything/datasource/db-service';
-import type { TDShape } from '@toeverything/components/board-types';
import { Editor } from '@toeverything/components/board-shapes';
+import type { TDShape } from '@toeverything/components/board-types';
+import type { ReturnEditorBlock } from '@toeverything/datasource/db-service';
+import { services } from '@toeverything/datasource/db-service';
import { usePageClientWidth } from '@toeverything/datasource/state';
+import { useEffect, useState } from 'react';
+
+const getBindings = (workspace: string, rootBlockId: string) => {
+ return services.api.editorBlock
+ .get({
+ workspace: workspace,
+ ids: [rootBlockId],
+ })
+ .then(blcoks => {
+ return blcoks[0].properties.bindings?.value;
+ });
+};
export const useShapes = (workspace: string, rootBlockId: string) => {
const { pageClientWidth } = usePageClientWidth();
// page padding left and right total 300px
const editorShapeInitSize = pageClientWidth - 300;
- const [blocks, setBlocks] = useState();
+ const [blocks, setBlocks] = useState<{
+ shapes: [ReturnEditorBlock[]];
+ bindings: string;
+ }>();
useEffect(() => {
- services.api.editorBlock
- .get({ workspace, ids: [rootBlockId] })
- .then(async blockData => {
- const shapes = await Promise.all(
- (blockData?.[0]?.children || []).map(async childId => {
- const childBlock = (
- await services.api.editorBlock.get({
- workspace,
- ids: [childId],
- })
- )?.[0];
- return childBlock;
- })
- );
- setBlocks(shapes);
+ Promise.all([
+ services.api.editorBlock
+ .get({ workspace, ids: [rootBlockId] })
+ .then(async blockData => {
+ const shapes = await Promise.all(
+ (blockData?.[0]?.children || []).map(async childId => {
+ const childBlock = (
+ await services.api.editorBlock.get({
+ workspace,
+ ids: [childId],
+ })
+ )?.[0];
+ return childBlock;
+ })
+ );
+ return shapes;
+ }),
+ ]).then(shapes => {
+ getBindings(workspace, rootBlockId).then(bindings => {
+ setBlocks({
+ shapes,
+ bindings: bindings,
+ });
});
+ });
+
let unobserve: () => void;
services.api.editorBlock
.observe({ workspace, id: rootBlockId }, async blockData => {
- const shapes = await Promise.all(
+ Promise.all(
(blockData?.children || []).map(async childId => {
const childBlock = (
await services.api.editorBlock.get({
@@ -40,8 +64,14 @@ export const useShapes = (workspace: string, rootBlockId: string) => {
)?.[0];
return childBlock;
})
- );
- setBlocks(shapes);
+ ).then(shapes => {
+ getBindings(workspace, rootBlockId).then(bindings => {
+ setBlocks({
+ shapes: [shapes],
+ bindings: bindings,
+ });
+ });
+ });
})
.then(cb => {
unobserve = cb;
@@ -53,8 +83,7 @@ export const useShapes = (workspace: string, rootBlockId: string) => {
}, [workspace, rootBlockId]);
let groupCount = 0;
-
- return blocks?.reduce((acc, block) => {
+ let blocksShapes = blocks?.shapes[0]?.reduce((acc, block) => {
const shapeProps = block.properties.shapeProps?.value
? JSON.parse(block.properties.shapeProps.value)
: {};
@@ -75,4 +104,8 @@ export const useShapes = (workspace: string, rootBlockId: string) => {
return acc;
}, {} as Record);
+ return {
+ shapes: blocksShapes,
+ bindings: JSON.parse(blocks?.bindings ?? '{}'),
+ };
};
diff --git a/libs/components/affine-editor/src/Editor.tsx b/libs/components/affine-editor/src/Editor.tsx
index 4f842de2fd..c280bea984 100644
--- a/libs/components/affine-editor/src/Editor.tsx
+++ b/libs/components/affine-editor/src/Editor.tsx
@@ -1,8 +1,8 @@
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import {
- RenderRoot,
RenderBlock,
+ RenderRoot,
type BlockEditor,
} from '@toeverything/components/editor-core';
import { useCurrentEditors } from '@toeverything/datasource/state';
@@ -17,7 +17,7 @@ interface AffineEditorProps {
*/
scrollBlank?: boolean;
- isWhiteboard?: boolean;
+ isEdgeless?: boolean;
scrollContainer?: HTMLElement;
scrollController?: {
@@ -29,12 +29,12 @@ interface AffineEditorProps {
function _useConstantWithDispose(
workspace: string,
rootBlockId: string,
- isWhiteboard: boolean
+ isEdgeless: boolean
) {
const ref = useRef<{ data: BlockEditor; onInit: boolean }>(null);
const { setCurrentEditors } = useCurrentEditors();
ref.current ??= {
- data: createEditor(workspace, rootBlockId, isWhiteboard),
+ data: createEditor(workspace, rootBlockId, isEdgeless),
onInit: true,
};
@@ -42,18 +42,14 @@ function _useConstantWithDispose(
if (ref.current.onInit) {
ref.current.onInit = false;
} else {
- ref.current.data = createEditor(
- workspace,
- rootBlockId,
- isWhiteboard
- );
+ ref.current.data = createEditor(workspace, rootBlockId, isEdgeless);
}
setCurrentEditors(prev => ({
...prev,
[rootBlockId]: ref.current.data,
}));
return () => ref.current.data.dispose();
- }, [workspace, rootBlockId, isWhiteboard, setCurrentEditors]);
+ }, [workspace, rootBlockId, isEdgeless, setCurrentEditors]);
return ref.current.data;
}
@@ -64,7 +60,7 @@ export const AffineEditor = forwardRef(
workspace,
rootBlockId,
scrollBlank = true,
- isWhiteboard,
+ isEdgeless,
scrollController,
scrollContainer,
},
@@ -73,7 +69,7 @@ export const AffineEditor = forwardRef(
const editor = _useConstantWithDispose(
workspace,
rootBlockId,
- isWhiteboard
+ isEdgeless
);
useEffect(() => {
diff --git a/libs/components/affine-editor/src/create-editor.ts b/libs/components/affine-editor/src/create-editor.ts
index 7d575c5500..6075e7a9af 100644
--- a/libs/components/affine-editor/src/create-editor.ts
+++ b/libs/components/affine-editor/src/create-editor.ts
@@ -1,36 +1,36 @@
-import { BlockEditor } from '@toeverything/framework/virgo';
import {
- PageBlock,
- RefLinkBlock,
- TextBlock,
+ BulletBlock,
+ CalloutBlock,
+ CodeBlock,
+ DividerBlock,
+ EmbedLinkBlock,
+ FigmaBlock,
+ // TocBlock,
+ FileBlock,
+ GridBlock,
+ GridItemBlock,
+ GroupBlock,
+ GroupDividerBlock,
Heading1Block,
Heading2Block,
Heading3Block,
- QuoteBlock,
- TodoBlock,
- CodeBlock,
- // TocBlock,
- FileBlock,
ImageBlock,
- DividerBlock,
- CalloutBlock,
- YoutubeBlock,
- FigmaBlock,
- GroupBlock,
- EmbedLinkBlock,
- BulletBlock,
NumberedBlock,
- GridBlock,
- GridItemBlock,
- GroupDividerBlock,
+ PageBlock,
+ QuoteBlock,
+ RefLinkBlock,
+ TextBlock,
+ TodoBlock,
+ YoutubeBlock,
} from '@toeverything/components/editor-blocks';
-import { Protocol } from '@toeverything/datasource/db-service';
import { plugins } from '@toeverything/components/editor-plugins';
+import { Protocol } from '@toeverything/datasource/db-service';
+import { BlockEditor } from '@toeverything/framework/virgo';
export const createEditor = (
workspace: string,
rootBlockId: string,
- isWhiteboard?: boolean
+ isEdgeless?: boolean
) => {
const blockEditor = new BlockEditor({
workspace,
@@ -61,7 +61,7 @@ export const createEditor = (
[Protocol.Block.Type.groupDivider]: new GroupDividerBlock(),
},
plugins,
- isWhiteboard,
+ isEdgeless,
});
return blockEditor;
diff --git a/libs/components/affine-editor/src/index.ts b/libs/components/affine-editor/src/index.ts
index 728c60c410..41a2f8b3d7 100644
--- a/libs/components/affine-editor/src/index.ts
+++ b/libs/components/affine-editor/src/index.ts
@@ -1,2 +1,2 @@
-export { AffineEditor } from './Editor';
export { createEditor } from './create-editor';
+export { AffineEditor } from './Editor';
diff --git a/libs/components/board-commands/src/align-shapes.ts b/libs/components/board-commands/src/align-shapes.ts
index 046f0974bb..3e798d20a1 100644
--- a/libs/components/board-commands/src/align-shapes.ts
+++ b/libs/components/board-commands/src/align-shapes.ts
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
-import { Vec } from '@tldraw/vec';
import { Utils } from '@tldraw/core';
+import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
AlignType,
- TldrawCommand,
TDShapeType,
+ TldrawCommand,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function alignShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/change-page.ts b/libs/components/board-commands/src/change-page.ts
index 1ebeac50dc..787c29dca8 100644
--- a/libs/components/board-commands/src/change-page.ts
+++ b/libs/components/board-commands/src/change-page.ts
@@ -1,5 +1,5 @@
-import type { TldrawCommand } from '@toeverything/components/board-types';
import type { TldrawApp } from '@toeverything/components/board-state';
+import type { TldrawCommand } from '@toeverything/components/board-types';
export function changePage(app: TldrawApp, pageId: string): TldrawCommand {
return {
diff --git a/libs/components/board-commands/src/create-page.ts b/libs/components/board-commands/src/create-page.ts
index 97bd471084..e6255bf409 100644
--- a/libs/components/board-commands/src/create-page.ts
+++ b/libs/components/board-commands/src/create-page.ts
@@ -1,9 +1,9 @@
-import type {
- TldrawCommand,
- TDPage,
-} from '@toeverything/components/board-types';
-import { Utils, TLPageState } from '@tldraw/core';
+import { TLPageState, Utils } from '@tldraw/core';
import type { TldrawApp } from '@toeverything/components/board-state';
+import type {
+ TDPage,
+ TldrawCommand,
+} from '@toeverything/components/board-types';
export function createPage(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/create-shapes.ts b/libs/components/board-commands/src/create-shapes.ts
index eaa5b9de6d..6ebff1ca0b 100644
--- a/libs/components/board-commands/src/create-shapes.ts
+++ b/libs/components/board-commands/src/create-shapes.ts
@@ -1,10 +1,10 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
import type {
Patch,
+ TDBinding,
TDShape,
TldrawCommand,
- TDBinding,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function createShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/delete-page.ts b/libs/components/board-commands/src/delete-page.ts
index ed0b6969de..0cde6bf91b 100644
--- a/libs/components/board-commands/src/delete-page.ts
+++ b/libs/components/board-commands/src/delete-page.ts
@@ -1,5 +1,5 @@
-import type { TldrawCommand } from '@toeverything/components/board-types';
import type { TldrawApp } from '@toeverything/components/board-state';
+import type { TldrawCommand } from '@toeverything/components/board-types';
export function deletePage(app: TldrawApp, pageId: string): TldrawCommand {
const {
diff --git a/libs/components/board-commands/src/delete-shapes.ts b/libs/components/board-commands/src/delete-shapes.ts
index 2c5daec09c..4b3407bbc8 100644
--- a/libs/components/board-commands/src/delete-shapes.ts
+++ b/libs/components/board-commands/src/delete-shapes.ts
@@ -1,9 +1,9 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
import type {
TDAsset,
TDAssets,
TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
import { removeShapesFromPage } from './shared/remove-shapes-from-page';
const removeAssetsFromDocument = (assets: TDAssets, idsToRemove: string[]) => {
diff --git a/libs/components/board-commands/src/distribute-shapes.ts b/libs/components/board-commands/src/distribute-shapes.ts
index 7840ed3cfb..e6bc5256ea 100644
--- a/libs/components/board-commands/src/distribute-shapes.ts
+++ b/libs/components/board-commands/src/distribute-shapes.ts
@@ -1,14 +1,14 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { Utils } from '@tldraw/core';
+import Vec from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
DistributeType,
TDShape,
- TldrawCommand,
TDShapeType,
+ TldrawCommand,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
-import Vec from '@tldraw/vec';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function distributeShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/duplicate-page.ts b/libs/components/board-commands/src/duplicate-page.ts
index b8a461c8d5..2ca092a8b7 100644
--- a/libs/components/board-commands/src/duplicate-page.ts
+++ b/libs/components/board-commands/src/duplicate-page.ts
@@ -1,6 +1,6 @@
-import type { TldrawCommand } from '@toeverything/components/board-types';
import { Utils } from '@tldraw/core';
import type { TldrawApp } from '@toeverything/components/board-state';
+import type { TldrawCommand } from '@toeverything/components/board-types';
export function duplicatePage(app: TldrawApp, pageId: string): TldrawCommand {
const newId = Utils.uniqueId();
diff --git a/libs/components/board-commands/src/duplicate-shapes.ts b/libs/components/board-commands/src/duplicate-shapes.ts
index 55a44f3821..eb058fee89 100644
--- a/libs/components/board-commands/src/duplicate-shapes.ts
+++ b/libs/components/board-commands/src/duplicate-shapes.ts
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { Utils } from '@tldraw/core';
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
import { TLDR } from '@toeverything/components/board-state';
import type {
PagePartial,
- TldrawCommand,
TDShape,
+ TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function duplicateShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/flip-shapes.ts b/libs/components/board-commands/src/flip-shapes.ts
index 53302753f5..01837703ce 100644
--- a/libs/components/board-commands/src/flip-shapes.ts
+++ b/libs/components/board-commands/src/flip-shapes.ts
@@ -1,8 +1,8 @@
-import { FlipType } from '@toeverything/components/board-types';
import { TLBoundsCorner, Utils } from '@tldraw/core';
-import type { TldrawCommand } from '@toeverything/components/board-types';
import type { TldrawApp } from '@toeverything/components/board-state';
import { TLDR } from '@toeverything/components/board-state';
+import type { TldrawCommand } from '@toeverything/components/board-types';
+import { FlipType } from '@toeverything/components/board-types';
export function flipShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/group-shapes.ts b/libs/components/board-commands/src/group-shapes.ts
index 5f0273174c..0e07e736fa 100644
--- a/libs/components/board-commands/src/group-shapes.ts
+++ b/libs/components/board-commands/src/group-shapes.ts
@@ -1,12 +1,12 @@
-import { TDShape, TDShapeType } from '@toeverything/components/board-types';
import { Utils } from '@tldraw/core';
-import type {
- Patch,
- TldrawCommand,
- TDBinding,
-} from '@toeverything/components/board-types';
import type { TldrawApp } from '@toeverything/components/board-state';
import { TLDR } from '@toeverything/components/board-state';
+import type {
+ Patch,
+ TDBinding,
+ TldrawCommand,
+} from '@toeverything/components/board-types';
+import { TDShape, TDShapeType } from '@toeverything/components/board-types';
export function groupShapes(
app: TldrawApp,
@@ -100,6 +100,7 @@ export function groupShapes(
afterShapes[groupId] = TLDR.get_shape_util(TDShapeType.Group).create({
id: groupId,
+ affineId: groupId,
childIndex: groupChildIndex,
parentId: groupParentId,
point: [groupBounds.minX, groupBounds.minY],
@@ -217,7 +218,6 @@ export function groupShapes(
}
}
});
-
return {
id: 'group',
before: {
diff --git a/libs/components/board-commands/src/index.ts b/libs/components/board-commands/src/index.ts
index 62314e9264..84d5f7f41c 100644
--- a/libs/components/board-commands/src/index.ts
+++ b/libs/components/board-commands/src/index.ts
@@ -10,10 +10,12 @@ export * from './duplicate-shapes';
export * from './flip-shapes';
export * from './group-shapes';
export * from './move-shapes-to-page';
-export * from './reorder-shapes';
export * from './rename-page';
+export * from './reorder-shapes';
export * from './reset-bounds';
export * from './rotate-shapes';
+export * from './set-shapes-lock-status';
+export * from './set-shapes-props';
export * from './stretch-shapes';
export * from './style-shapes';
export * from './toggle-shapes-decoration';
@@ -21,5 +23,3 @@ export * from './toggle-shapes-prop';
export * from './translate-shapes';
export * from './ungroup-shapes';
export * from './update-shapes';
-export * from './set-shapes-props';
-export * from './set-shapes-lock-status';
diff --git a/libs/components/board-commands/src/move-shapes-to-page.ts b/libs/components/board-commands/src/move-shapes-to-page.ts
index f8d7c64ea7..766a4a4611 100644
--- a/libs/components/board-commands/src/move-shapes-to-page.ts
+++ b/libs/components/board-commands/src/move-shapes-to-page.ts
@@ -1,14 +1,14 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
+import { TLBounds, Utils } from '@tldraw/core';
+import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import type {
ArrowShape,
PagePartial,
- TldrawCommand,
TDShape,
+ TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
-import { TLDR } from '@toeverything/components/board-state';
-import { Utils, TLBounds } from '@tldraw/core';
-import { Vec } from '@tldraw/vec';
export function moveShapesToPage(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/rename-page.ts b/libs/components/board-commands/src/rename-page.ts
index 27062ded39..2cccfdbe0a 100644
--- a/libs/components/board-commands/src/rename-page.ts
+++ b/libs/components/board-commands/src/rename-page.ts
@@ -1,5 +1,5 @@
-import type { TldrawCommand } from '@toeverything/components/board-types';
import type { TldrawApp } from '@toeverything/components/board-state';
+import type { TldrawCommand } from '@toeverything/components/board-types';
export function renamePage(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/reorder-shapes.ts b/libs/components/board-commands/src/reorder-shapes.ts
index 30a96a188a..929030446f 100644
--- a/libs/components/board-commands/src/reorder-shapes.ts
+++ b/libs/components/board-commands/src/reorder-shapes.ts
@@ -1,10 +1,10 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
MoveType,
TDShape,
TldrawCommand,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function reorderShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/reset-bounds.ts b/libs/components/board-commands/src/reset-bounds.ts
index f231c494cf..a033832465 100644
--- a/libs/components/board-commands/src/reset-bounds.ts
+++ b/libs/components/board-commands/src/reset-bounds.ts
@@ -1,6 +1,6 @@
-import type { TldrawCommand } from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
+import type { TldrawCommand } from '@toeverything/components/board-types';
export function resetBounds(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/rotate-shapes.ts b/libs/components/board-commands/src/rotate-shapes.ts
index 073744a9a4..2e9b8444cc 100644
--- a/libs/components/board-commands/src/rotate-shapes.ts
+++ b/libs/components/board-commands/src/rotate-shapes.ts
@@ -1,10 +1,10 @@
import { Utils } from '@tldraw/core';
-import type {
- TldrawCommand,
- TDShape,
-} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
+import type {
+ TDShape,
+ TldrawCommand,
+} from '@toeverything/components/board-types';
const PI2 = Math.PI * 2;
diff --git a/libs/components/board-commands/src/set-shapes-lock-status.ts b/libs/components/board-commands/src/set-shapes-lock-status.ts
index ea220e1ea1..05ea0bd5e4 100644
--- a/libs/components/board-commands/src/set-shapes-lock-status.ts
+++ b/libs/components/board-commands/src/set-shapes-lock-status.ts
@@ -1,8 +1,8 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
import type {
TDShape,
TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function setShapesLockStatus(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/set-shapes-props.ts b/libs/components/board-commands/src/set-shapes-props.ts
index 39f5596589..a8b7582c4d 100644
--- a/libs/components/board-commands/src/set-shapes-props.ts
+++ b/libs/components/board-commands/src/set-shapes-props.ts
@@ -1,8 +1,8 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
import type {
TDShape,
TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function setShapesProps(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/stretch-shapes.ts b/libs/components/board-commands/src/stretch-shapes.ts
index cc44699d25..e68bbee6e0 100644
--- a/libs/components/board-commands/src/stretch-shapes.ts
+++ b/libs/components/board-commands/src/stretch-shapes.ts
@@ -1,9 +1,9 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { TLBoundsCorner, Utils } from '@tldraw/core';
-import { StretchType, TDShapeType } from '@toeverything/components/board-types';
-import type { TldrawCommand } from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
+import type { TldrawCommand } from '@toeverything/components/board-types';
+import { StretchType, TDShapeType } from '@toeverything/components/board-types';
export function stretchShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/style-shapes.ts b/libs/components/board-commands/src/style-shapes.ts
index 08e6118979..bb3e248a54 100644
--- a/libs/components/board-commands/src/style-shapes.ts
+++ b/libs/components/board-commands/src/style-shapes.ts
@@ -1,14 +1,11 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
Patch,
ShapeStyles,
- TldrawCommand,
TDShape,
- // TDShapeType,
- // TextShape
+ TldrawCommand,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
-import { Vec } from '@tldraw/vec';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function styleShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/toggle-shapes-decoration.ts b/libs/components/board-commands/src/toggle-shapes-decoration.ts
index 38bde36380..443cb3b8ab 100644
--- a/libs/components/board-commands/src/toggle-shapes-decoration.ts
+++ b/libs/components/board-commands/src/toggle-shapes-decoration.ts
@@ -1,10 +1,10 @@
-import { Decoration } from '@toeverything/components/board-types';
+import type { TldrawApp } from '@toeverything/components/board-state';
import type {
- Patch,
ArrowShape,
+ Patch,
TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
+import { Decoration } from '@toeverything/components/board-types';
export function toggleShapesDecoration(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/toggle-shapes-prop.ts b/libs/components/board-commands/src/toggle-shapes-prop.ts
index 374c47cc8e..f52c55986b 100644
--- a/libs/components/board-commands/src/toggle-shapes-prop.ts
+++ b/libs/components/board-commands/src/toggle-shapes-prop.ts
@@ -1,8 +1,8 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
import type {
TDShape,
TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function toggleShapesProp(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/translate-shapes.ts b/libs/components/board-commands/src/translate-shapes.ts
index d0dbe28c55..4da1a2a709 100644
--- a/libs/components/board-commands/src/translate-shapes.ts
+++ b/libs/components/board-commands/src/translate-shapes.ts
@@ -1,10 +1,10 @@
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
import { TLDR } from '@toeverything/components/board-state';
import type {
- TldrawCommand,
PagePartial,
+ TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function translateShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/ungroup-shapes.ts b/libs/components/board-commands/src/ungroup-shapes.ts
index bbf1ee0a1a..160c46819a 100644
--- a/libs/components/board-commands/src/ungroup-shapes.ts
+++ b/libs/components/board-commands/src/ungroup-shapes.ts
@@ -1,12 +1,12 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
import { TLDR } from '@toeverything/components/board-state';
import type {
- Patch,
GroupShape,
+ Patch,
TDBinding,
TDShape,
TldrawCommand,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
export function ungroupShapes(
app: TldrawApp,
diff --git a/libs/components/board-commands/src/update-shapes.ts b/libs/components/board-commands/src/update-shapes.ts
index d5317b4c3e..3041906345 100644
--- a/libs/components/board-commands/src/update-shapes.ts
+++ b/libs/components/board-commands/src/update-shapes.ts
@@ -1,9 +1,9 @@
-import type {
- TldrawCommand,
- TDShape,
-} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
+import type {
+ TDShape,
+ TldrawCommand,
+} from '@toeverything/components/board-types';
export function updateShapes(
app: TldrawApp,
diff --git a/libs/components/board-draw/src/TlDraw.tsx b/libs/components/board-draw/src/TlDraw.tsx
index 1e95506ab0..1961367235 100644
--- a/libs/components/board-draw/src/TlDraw.tsx
+++ b/libs/components/board-draw/src/TlDraw.tsx
@@ -1,43 +1,43 @@
/* eslint-disable max-lines */
+import { Renderer } from '@tldraw/core';
+import { shapeUtils } from '@toeverything/components/board-shapes';
+import {
+ TLDR,
+ TldrawApp,
+ TldrawAppCtorProps,
+} from '@toeverything/components/board-state';
+import {
+ GRID_SIZE,
+ TDDocument,
+ TDMeta,
+ TDStatus,
+} from '@toeverything/components/board-types';
+import { styled } from '@toeverything/components/ui';
+// import { FocusButton } from '~components/FocusButton';
+import { usePageClientWidth } from '@toeverything/datasource/state';
import {
memo,
useEffect,
useLayoutEffect,
- useRef,
useMemo,
+ useRef,
useState,
type RefObject,
} from 'react';
-import { Renderer } from '@tldraw/core';
-import { styled } from '@toeverything/components/ui';
-import {
- TDDocument,
- TDStatus,
- GRID_SIZE,
- TDMeta,
-} from '@toeverything/components/board-types';
-import {
- TldrawApp,
- TldrawAppCtorProps,
- TLDR,
-} from '@toeverything/components/board-state';
-import {
- TldrawContext,
- useStylesheet,
- useKeyboardShortcuts,
- useTldrawApp,
-} from './hooks';
-import { shapeUtils } from '@toeverything/components/board-shapes';
-import { ToolsPanel } from './components/tools-panel';
+import { ErrorBoundary } from 'react-error-boundary';
+import { CommandPanel } from './components/command-panel';
// import { TopPanel } from '~components/TopPanel';
import { ContextMenu } from './components/context-menu';
-// import { FocusButton } from '~components/FocusButton';
-import { Loading } from './components/loading';
-import { ErrorBoundary } from 'react-error-boundary';
import { ErrorFallback } from './components/error-fallback';
+import { Loading } from './components/loading';
+import { ToolsPanel } from './components/tools-panel';
import { ZoomBar } from './components/zoom-bar';
-import { CommandPanel } from './components/command-panel';
-import { usePageClientWidth } from '@toeverything/datasource/state';
+import {
+ TldrawContext,
+ useKeyboardShortcuts,
+ useStylesheet,
+ useTldrawApp,
+} from './hooks';
export interface TldrawProps extends TldrawAppCtorProps {
/**
@@ -295,7 +295,6 @@ const InnerTldraw = memo(function InnerTldraw({
const pageState = document.pageStates[page.id];
const assets = document.assets;
const { selectedIds } = pageState;
-
const isHideBoundsShape =
selectedIds.length === 1 &&
page.shapes[selectedIds[0]] &&
diff --git a/libs/components/board-draw/src/components/align-panel/index.tsx b/libs/components/board-draw/src/components/align-panel/index.tsx
new file mode 100644
index 0000000000..d0ff48390d
--- /dev/null
+++ b/libs/components/board-draw/src/components/align-panel/index.tsx
@@ -0,0 +1,66 @@
+import { styled, Tooltip } from '@toeverything/components/ui';
+import { AlignType } from '../command-panel/AlignOperation';
+
+interface AlignObject {
+ name?: string;
+ /**
+ * color: none means no color
+ */
+ title: string;
+ icon?: JSX.Element;
+}
+/**
+ * ColorValue : none means no color
+ */
+interface AlignProps {
+ alignOptions: AlignObject[];
+ selected?: string;
+ onSelect?: (alginType: AlignType) => void;
+}
+
+export const AlignPanel = ({
+ alignOptions,
+ selected,
+ onSelect,
+}: AlignProps) => {
+ return (
+
+ {alignOptions.map(alignOption => {
+ const option = alignOption.name as AlignType;
+ // const selected = color;
+ return (
+
+ {
+ onSelect?.(option);
+ }}
+ >
+ {alignOption.icon}
+
+
+ );
+ })}
+
+ );
+};
+
+const Container = styled('div')({
+ width: '170px',
+ display: 'flex',
+ flexWrap: 'wrap',
+});
+
+const SelectableContainer = styled('div')<{ selected?: boolean }>(
+ ({ selected, theme }) => ({
+ color: theme.affine.palette.icons,
+ borderRadius: '5px',
+ overflow: 'hidden',
+ margin: '5px',
+ padding: '3px',
+ cursor: 'pointer',
+ boxSizing: 'border-box',
+ '&:hover': {
+ backgroundColor: theme.affine.palette.hover,
+ },
+ })
+);
diff --git a/libs/components/board-draw/src/components/command-panel/AlignOperation.tsx b/libs/components/board-draw/src/components/command-panel/AlignOperation.tsx
new file mode 100644
index 0000000000..d8f5b307e4
--- /dev/null
+++ b/libs/components/board-draw/src/components/command-panel/AlignOperation.tsx
@@ -0,0 +1,108 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { DistributeType, TDShape } from '@toeverything/components/board-types';
+import {
+ AlignIcon,
+ ShapesAlignBottomIcon,
+ ShapesAlignHorizontalCenterIcon,
+ ShapesAlignLeftIcon,
+ ShapesAlignRightIcon,
+ ShapesAlignTopIcon,
+ ShapesAlignVerticalCenterIcon,
+ ShapesDistributeHorizontalIcon,
+ ShapesDistributeVerticalIcon,
+} from '@toeverything/components/icons';
+import { IconButton, Popover, Tooltip } from '@toeverything/components/ui';
+import { AlignPanel } from '../align-panel';
+interface BorderColorConfigProps {
+ app: TldrawApp;
+ shapes: TDShape[];
+}
+
+export enum AlignType {
+ Top = 'top',
+ CenterVertical = 'centerVertical',
+ Bottom = 'bottom',
+ Left = 'left',
+ CenterHorizontal = 'centerHorizontal',
+ Right = 'right',
+}
+
+let AlignPanelArr = [
+ {
+ name: 'left',
+ title: 'Align left',
+ icon: ,
+ },
+ {
+ name: 'centerVertical',
+ title: 'Align Center Vertical',
+ icon: ,
+ },
+ {
+ name: 'right',
+ title: 'Align right',
+ icon: ,
+ },
+ {
+ name: 'top',
+ title: 'Align top',
+ icon: ,
+ },
+ {
+ name: 'bottom',
+ title: 'Align bottom',
+ icon: ,
+ },
+
+ {
+ name: 'centerHorizontal',
+ title: 'Align centerHorizontal',
+ icon: (
+
+ ),
+ },
+ {
+ name: 'distributeCenterHorizontal',
+ title: 'Align distribute center horizontal',
+ icon: ,
+ },
+ {
+ name: 'distributeCenterVertical',
+ title: 'Align distribute center horizontal',
+ icon: ,
+ },
+];
+export const AlignOperation = ({ app, shapes }: BorderColorConfigProps) => {
+ const setAlign = (alginType: string) => {
+ switch (alginType) {
+ case 'distributeCenterHorizontal':
+ app.distribute(DistributeType.Horizontal);
+ break;
+ case 'distributeCenterVertical':
+ app.distribute(DistributeType.Vertical);
+ break;
+ default:
+ app.align(alginType as AlignType);
+ break;
+ }
+ };
+
+ return (
+
+ }
+ >
+
+
+
+
+
+
+ );
+};
diff --git a/libs/components/board-draw/src/components/command-panel/ArrowTo.tsx b/libs/components/board-draw/src/components/command-panel/ArrowTo.tsx
new file mode 100644
index 0000000000..21f37a9fbc
--- /dev/null
+++ b/libs/components/board-draw/src/components/command-panel/ArrowTo.tsx
@@ -0,0 +1,78 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
+import type {
+ ArrowBinding,
+ TDShape,
+} from '@toeverything/components/board-types';
+import { ConnectorIcon } from '@toeverything/components/icons';
+import { IconButton, Popover, Tooltip } from '@toeverything/components/ui';
+import { useEffect, useState } from 'react';
+import { ListItemContainer, ListItemTitle } from './FontSizeConfig';
+
+interface GroupAndUnGroupProps {
+ app: TldrawApp;
+ shapes: TDShape[];
+}
+
+export const ArrowTo = ({ app, shapes }: GroupAndUnGroupProps) => {
+ const [arrowToArr, setarrowToArr] = useState([]);
+ useEffect(() => {
+ let allShape = app.shapes;
+ let bindings = app.page.bindings;
+ let activeShape = shapes[0];
+ let toNextShapBindings: ArrowBinding[] = [];
+ let bindingId = '';
+ Object.keys(bindings).forEach(key => {
+ if (bindings[key].toId === activeShape.id) {
+ bindingId = bindings[key].fromId;
+ }
+ });
+ Object.keys(bindings).forEach(key => {
+ if (bindings[key].fromId === bindingId) {
+ toNextShapBindings.push(bindings[key]);
+ }
+ });
+ let ArrowToArr: TDShape[] = [];
+ toNextShapBindings.forEach(binding => {
+ if (binding.toId !== activeShape.id) {
+ allShape.forEach(item => {
+ console.log(item);
+ if (item.id === binding.toId) {
+ ArrowToArr.push(item);
+ }
+ });
+ }
+ });
+ setarrowToArr(ArrowToArr);
+ return () => {};
+ }, [app.page.bindings, app.shapes]);
+ const jumpToNextShap = (shape: TDShape) => {
+ app.zoomToShapes([shape]);
+ };
+
+ return (
+
+ {arrowToArr.map((arrow: any) => {
+ return (
+ jumpToNextShap(arrow)}
+ >
+ {arrow.name}
+
+ );
+ })}
+
+ }
+ >
+
+
+
+
+
+
+ );
+};
diff --git a/libs/components/board-draw/src/components/command-panel/BorderColorConfig.tsx b/libs/components/board-draw/src/components/command-panel/BorderColorConfig.tsx
index b5e9f2f073..15d6eadc18 100644
--- a/libs/components/board-draw/src/components/command-panel/BorderColorConfig.tsx
+++ b/libs/components/board-draw/src/components/command-panel/BorderColorConfig.tsx
@@ -1,13 +1,13 @@
import type { TldrawApp } from '@toeverything/components/board-state';
import type { TDShape } from '@toeverything/components/board-types';
-import { Popover, Tooltip, IconButton } from '@toeverything/components/ui';
import {
- BorderColorNoneIcon,
BorderColorDuotoneIcon,
+ BorderColorNoneIcon,
} from '@toeverything/components/icons';
+import { IconButton, Popover, Tooltip } from '@toeverything/components/ui';
import { countBy, maxBy } from '@toeverything/utils';
-import { getShapeIds } from './utils';
import { Palette } from '../palette';
+import { getShapeIds } from './utils';
interface BorderColorConfigProps {
app: TldrawApp;
diff --git a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx
index b8dece4cc1..94e28bdc2f 100644
--- a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx
+++ b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx
@@ -1,16 +1,18 @@
+import { TLDR, TldrawApp } from '@toeverything/components/board-state';
+import { Divider, Popover, styled } from '@toeverything/components/ui';
import { Fragment } from 'react';
-import { Vec } from '@tldraw/vec';
-import { TldrawApp, TLDR } from '@toeverything/components/board-state';
-import { Popover, styled, Divider } from '@toeverything/components/ui';
-import { getAnchor, useConfig } from './utils';
+import { AlignOperation } from './AlignOperation';
+import { ArrowTo } from './ArrowTo';
import { BorderColorConfig } from './BorderColorConfig';
+import { DeleteShapes } from './DeleteOperation';
import { FillColorConfig } from './FillColorConfig';
import { FontSizeConfig } from './FontSizeConfig';
-import { StrokeLineStyleConfig } from './stroke-line-style-config';
-import { Group, UnGroup } from './GroupOperation';
-import { DeleteShapes } from './DeleteOperation';
-import { Lock, Unlock } from './LockOperation';
import { FrameFillColorConfig } from './FrameFillColorConfig';
+import { Group, UnGroup } from './GroupOperation';
+import { Lock, Unlock } from './LockOperation';
+import { MoveCoverageConfig } from './MoveCoverage';
+import { StrokeLineStyleConfig } from './stroke-line-style-config';
+import { getAnchor, useConfig } from './utils';
export const CommandPanel = ({ app }: { app: TldrawApp }) => {
const state = app.useStore();
@@ -92,6 +94,25 @@ export const CommandPanel = ({ app }: { app: TldrawApp }) => {
shapes={config.deleteShapes.selectedShapes}
/>
),
+ moveCoverageConfig: (
+
+ ),
+ alginOperation: config.group.selectedShapes.length ? (
+
+ ) : null,
+ toNextShap: (
+
+ ),
};
const nodes = Object.entries(configNodes).filter(([key, node]) => !!node);
diff --git a/libs/components/board-draw/src/components/command-panel/DeleteOperation.tsx b/libs/components/board-draw/src/components/command-panel/DeleteOperation.tsx
index 474fee5dc0..74351af178 100644
--- a/libs/components/board-draw/src/components/command-panel/DeleteOperation.tsx
+++ b/libs/components/board-draw/src/components/command-panel/DeleteOperation.tsx
@@ -1,7 +1,7 @@
import type { TldrawApp } from '@toeverything/components/board-state';
import type { TDShape } from '@toeverything/components/board-types';
-import { IconButton, Tooltip } from '@toeverything/components/ui';
import { DeleteCashBinIcon } from '@toeverything/components/icons';
+import { IconButton, Tooltip } from '@toeverything/components/ui';
import { getShapeIds } from './utils';
interface DeleteShapesProps {
diff --git a/libs/components/board-draw/src/components/command-panel/FillColorConfig.tsx b/libs/components/board-draw/src/components/command-panel/FillColorConfig.tsx
index 70f4738390..909b65eca4 100644
--- a/libs/components/board-draw/src/components/command-panel/FillColorConfig.tsx
+++ b/libs/components/board-draw/src/components/command-panel/FillColorConfig.tsx
@@ -1,18 +1,18 @@
import type { TldrawApp } from '@toeverything/components/board-state';
import type { TDShape } from '@toeverything/components/board-types';
import {
+ ShapeColorDuotoneIcon,
+ ShapeColorNoneIcon,
+} from '@toeverything/components/icons';
+import {
+ IconButton,
Popover,
Tooltip,
- IconButton,
useTheme,
} from '@toeverything/components/ui';
-import {
- ShapeColorNoneIcon,
- ShapeColorDuotoneIcon,
-} from '@toeverything/components/icons';
import { countBy, maxBy } from '@toeverything/utils';
-import { getShapeIds } from './utils';
import { Palette } from '../palette';
+import { getShapeIds } from './utils';
interface BorderColorConfigProps {
app: TldrawApp;
diff --git a/libs/components/board-draw/src/components/command-panel/FontSizeConfig.tsx b/libs/components/board-draw/src/components/command-panel/FontSizeConfig.tsx
index 21d5cef043..38fbbfae22 100644
--- a/libs/components/board-draw/src/components/command-panel/FontSizeConfig.tsx
+++ b/libs/components/board-draw/src/components/command-panel/FontSizeConfig.tsx
@@ -2,17 +2,17 @@ import type { TldrawApp } from '@toeverything/components/board-state';
import type { TDShape } from '@toeverything/components/board-types';
import { FontSizeStyle } from '@toeverything/components/board-types';
import {
- Popover,
- Tooltip,
- IconButton,
- styled,
-} from '@toeverything/components/ui';
-import {
- TextFontIcon,
HeadingOneIcon,
- HeadingTwoIcon,
HeadingThreeIcon,
+ HeadingTwoIcon,
+ TextFontIcon,
} from '@toeverything/components/icons';
+import {
+ IconButton,
+ Popover,
+ styled,
+ Tooltip,
+} from '@toeverything/components/ui';
import { countBy, maxBy } from '@toeverything/utils';
import { getShapeIds } from './utils';
@@ -86,7 +86,7 @@ export const FontSizeConfig = ({ app, shapes }: FontSizeConfigProps) => {
);
};
-const ListItemContainer = styled('div')(({ theme }) => ({
+export const ListItemContainer = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
@@ -100,7 +100,7 @@ const ListItemContainer = styled('div')(({ theme }) => ({
},
}));
-const ListItemTitle = styled('span')(({ theme }) => ({
+export const ListItemTitle = styled('span')(({ theme }) => ({
marginLeft: '12px',
color: theme.affine.palette.primaryText,
}));
diff --git a/libs/components/board-draw/src/components/command-panel/FrameFillColorConfig.tsx b/libs/components/board-draw/src/components/command-panel/FrameFillColorConfig.tsx
index 1b107a962b..58a13927ec 100644
--- a/libs/components/board-draw/src/components/command-panel/FrameFillColorConfig.tsx
+++ b/libs/components/board-draw/src/components/command-panel/FrameFillColorConfig.tsx
@@ -1,18 +1,18 @@
import type { TldrawApp } from '@toeverything/components/board-state';
import type { TDShape } from '@toeverything/components/board-types';
import {
+ ShapeColorDuotoneIcon,
+ ShapeColorNoneIcon,
+} from '@toeverything/components/icons';
+import {
+ IconButton,
Popover,
Tooltip,
- IconButton,
useTheme,
} from '@toeverything/components/ui';
-import {
- ShapeColorNoneIcon,
- ShapeColorDuotoneIcon,
-} from '@toeverything/components/icons';
import { countBy, maxBy } from '@toeverything/utils';
-import { getShapeIds } from './utils';
import { Palette } from '../palette';
+import { getShapeIds } from './utils';
interface BorderColorConfigProps {
app: TldrawApp;
diff --git a/libs/components/board-draw/src/components/command-panel/GroupOperation.tsx b/libs/components/board-draw/src/components/command-panel/GroupOperation.tsx
index 954e2c3eb4..47aaaefa95 100644
--- a/libs/components/board-draw/src/components/command-panel/GroupOperation.tsx
+++ b/libs/components/board-draw/src/components/command-panel/GroupOperation.tsx
@@ -1,7 +1,8 @@
-import type { TldrawApp } from '@toeverything/components/board-state';
-import type { TDShape } from '@toeverything/components/board-types';
-import { IconButton, Tooltip } from '@toeverything/components/ui';
+import { TLDR, TldrawApp } from '@toeverything/components/board-state';
+import { TDShape, TDShapeType } from '@toeverything/components/board-types';
import { GroupIcon, UngroupIcon } from '@toeverything/components/icons';
+import { IconButton, Tooltip } from '@toeverything/components/ui';
+import { services } from '@toeverything/datasource/db-service';
import { getShapeIds } from './utils';
interface GroupAndUnGroupProps {
@@ -10,8 +11,38 @@ interface GroupAndUnGroupProps {
}
export const Group = ({ app, shapes }: GroupAndUnGroupProps) => {
- const group = () => {
- app.group(getShapeIds(shapes));
+ const group = async () => {
+ let groupShape = await services.api.editorBlock.create({
+ workspace: app.document.id,
+ parentId: app.appState.currentPageId,
+ type: 'shape',
+ });
+ await services.api.editorBlock.update({
+ workspace: groupShape.workspace,
+ id: groupShape.id,
+ properties: {
+ shapeProps: {
+ value: JSON.stringify(
+ TLDR.get_shape_util(TDShapeType.Group).create({
+ id: groupShape.id,
+ affineId: groupShape.id,
+ childIndex: 1,
+ parentId: app.appState.currentPageId,
+ point: [0, 0],
+ size: [0, 0],
+ children: getShapeIds(shapes),
+ workspace: app.document.id,
+ })
+ ),
+ },
+ },
+ });
+
+ app.group(
+ getShapeIds(shapes),
+ groupShape.id,
+ app.appState.currentPageId
+ );
};
return (
diff --git a/libs/components/board-draw/src/components/command-panel/LockOperation.tsx b/libs/components/board-draw/src/components/command-panel/LockOperation.tsx
index b16d8f26f1..b7de04969d 100644
--- a/libs/components/board-draw/src/components/command-panel/LockOperation.tsx
+++ b/libs/components/board-draw/src/components/command-panel/LockOperation.tsx
@@ -1,7 +1,7 @@
import type { TldrawApp } from '@toeverything/components/board-state';
import type { TDShape } from '@toeverything/components/board-types';
-import { IconButton, Tooltip } from '@toeverything/components/ui';
import { LockIcon, UnlockIcon } from '@toeverything/components/icons';
+import { IconButton, Tooltip } from '@toeverything/components/ui';
import { getShapeIds } from './utils';
interface GroupAndUnGroupProps {
diff --git a/libs/components/board-draw/src/components/command-panel/MoveCoverage.tsx b/libs/components/board-draw/src/components/command-panel/MoveCoverage.tsx
new file mode 100644
index 0000000000..cbca4224fa
--- /dev/null
+++ b/libs/components/board-draw/src/components/command-panel/MoveCoverage.tsx
@@ -0,0 +1,77 @@
+import type { TldrawApp } from '@toeverything/components/board-state';
+import type { TDShape } from '@toeverything/components/board-types';
+import {
+ BringForwardIcon,
+ BringToFrontIcon,
+ LayersIcon,
+ SendBackwardIcon,
+ SendToBackIcon,
+} from '@toeverything/components/icons';
+import { IconButton, Popover, Tooltip } from '@toeverything/components/ui';
+import { AlignPanel } from '../align-panel';
+
+interface FontSizeConfigProps {
+ app: TldrawApp;
+ shapes: TDShape[];
+}
+
+const AlignPanelArr = [
+ {
+ title: 'To Front',
+ name: 'tofront',
+ icon: ,
+ },
+ {
+ title: 'Forward',
+ name: 'forward',
+ icon: ,
+ },
+ {
+ title: 'Backward',
+ name: 'backward',
+ icon: ,
+ },
+ {
+ title: 'To Back',
+ name: 'toback',
+ icon: ,
+ },
+];
+
+export const MoveCoverageConfig = ({ app, shapes }: FontSizeConfigProps) => {
+ const moveCoverage = (type: string) => {
+ switch (type) {
+ case 'toback':
+ app.moveToBack();
+ break;
+ case 'backward':
+ app.moveBackward();
+ break;
+ case 'forward':
+ app.moveForward();
+ break;
+ case 'tofront':
+ app.moveToFront();
+ break;
+ }
+ };
+
+ return (
+
+ }
+ >
+
+
+
+
+
+
+ );
+};
diff --git a/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/LineStyle.tsx b/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/LineStyle.tsx
index 06e6bfb1de..b7d2a74b15 100644
--- a/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/LineStyle.tsx
+++ b/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/LineStyle.tsx
@@ -1,15 +1,15 @@
import { DashStyle, StrokeWidth } from '@toeverything/components/board-types';
import {
- LineNoneIcon,
- DashLineIcon,
- SolidLineIcon,
BrushIcon,
+ DashLineIcon,
+ LineNoneIcon,
+ SolidLineIcon,
} from '@toeverything/components/icons';
import {
IconButton,
+ Slider,
styled,
Tooltip,
- Slider,
} from '@toeverything/components/ui';
export const lineStyles = [
diff --git a/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/StrokeLineStyleConfig.tsx b/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/StrokeLineStyleConfig.tsx
index 3698d2dd86..3d90ac3970 100644
--- a/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/StrokeLineStyleConfig.tsx
+++ b/libs/components/board-draw/src/components/command-panel/stroke-line-style-config/StrokeLineStyleConfig.tsx
@@ -1,8 +1,8 @@
import type { TldrawApp } from '@toeverything/components/board-state';
-import { DashStyle, StrokeWidth } from '@toeverything/components/board-types';
import type { TDShape } from '@toeverything/components/board-types';
-import { Popover, IconButton, Tooltip } from '@toeverything/components/ui';
+import { DashStyle, StrokeWidth } from '@toeverything/components/board-types';
import { BrushIcon } from '@toeverything/components/icons';
+import { IconButton, Popover, Tooltip } from '@toeverything/components/ui';
import { countBy, maxBy } from '@toeverything/utils';
import { getShapeIds } from '../utils';
import { LineStyle, lineStyles } from './LineStyle';
diff --git a/libs/components/board-draw/src/components/command-panel/utils/index.ts b/libs/components/board-draw/src/components/command-panel/utils/index.ts
index ce623cad52..7b0c0f9343 100644
--- a/libs/components/board-draw/src/components/command-panel/utils/index.ts
+++ b/libs/components/board-draw/src/components/command-panel/utils/index.ts
@@ -1,2 +1,2 @@
export { getAnchor } from './get-anchor';
-export { useConfig, getShapeIds } from './use-config';
+export { getShapeIds, useConfig } from './use-config';
diff --git a/libs/components/board-draw/src/components/command-panel/utils/use-config.ts b/libs/components/board-draw/src/components/command-panel/utils/use-config.ts
index 6071eb8dcc..8236cbe36f 100644
--- a/libs/components/board-draw/src/components/command-panel/utils/use-config.ts
+++ b/libs/components/board-draw/src/components/command-panel/utils/use-config.ts
@@ -1,7 +1,7 @@
import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import type { TDShape } from '@toeverything/components/board-types';
import { TDShapeType } from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
interface Config {
type:
diff --git a/libs/components/board-draw/src/components/error-fallback/error-fallback.tsx b/libs/components/board-draw/src/components/error-fallback/error-fallback.tsx
index ff7e5c4935..6efbcbca97 100644
--- a/libs/components/board-draw/src/components/error-fallback/error-fallback.tsx
+++ b/libs/components/board-draw/src/components/error-fallback/error-fallback.tsx
@@ -1,7 +1,6 @@
-import * as React from 'react';
+import { styled } from '@toeverything/components/ui';
import { FallbackProps } from 'react-error-boundary';
import { useTldrawApp } from '../../hooks';
-import { styled } from '@toeverything/components/ui';
export function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
const app = useTldrawApp();
diff --git a/libs/components/board-draw/src/components/loading/loading.tsx b/libs/components/board-draw/src/components/loading/loading.tsx
index 8fb872426b..a0bf11dab1 100644
--- a/libs/components/board-draw/src/components/loading/loading.tsx
+++ b/libs/components/board-draw/src/components/loading/loading.tsx
@@ -1,7 +1,6 @@
-import * as React from 'react';
-import { useTldrawApp } from '../../hooks';
-import { styled } from '@toeverything/components/ui';
import type { TDSnapshot } from '@toeverything/components/board-types';
+import { styled } from '@toeverything/components/ui';
+import { useTldrawApp } from '../../hooks';
const loadingSelector = (s: TDSnapshot) => s.appState.isLoading;
diff --git a/libs/components/board-draw/src/components/palette/Palette.tsx b/libs/components/board-draw/src/components/palette/Palette.tsx
index ac2492d271..5ff84e8ca8 100644
--- a/libs/components/board-draw/src/components/palette/Palette.tsx
+++ b/libs/components/board-draw/src/components/palette/Palette.tsx
@@ -1,7 +1,6 @@
-import type { PropsWithChildren } from 'react';
-import { useMemo } from 'react';
-import { styled, Tooltip } from '@toeverything/components/ui';
import { ShapeColorNoneIcon } from '@toeverything/components/icons';
+import { styled, Tooltip } from '@toeverything/components/ui';
+import { useMemo } from 'react';
interface ColorObject {
name?: string;
diff --git a/libs/components/board-draw/src/components/tools-panel/LineTools.tsx b/libs/components/board-draw/src/components/tools-panel/LineTools.tsx
index 4a1ed06ada..3ef546ca3c 100644
--- a/libs/components/board-draw/src/components/tools-panel/LineTools.tsx
+++ b/libs/components/board-draw/src/components/tools-panel/LineTools.tsx
@@ -1,18 +1,18 @@
-import { useState, useEffect } from 'react';
import {
- ConnectorIcon,
- ConectorLineIcon,
ConectorArrowIcon,
+ ConectorLineIcon,
+ ConnectorIcon,
} from '@toeverything/components/icons';
import {
- Tooltip,
- Popover,
IconButton,
+ Popover,
styled,
+ Tooltip,
} from '@toeverything/components/ui';
+import { useEffect, useState } from 'react';
-import { TDSnapshot, TDShapeType } from '@toeverything/components/board-types';
import { TldrawApp } from '@toeverything/components/board-state';
+import { TDShapeType, TDSnapshot } from '@toeverything/components/board-types';
export type ShapeTypes = TDShapeType.Line | TDShapeType.Arrow;
diff --git a/libs/components/board-draw/src/components/tools-panel/ShapeTools.tsx b/libs/components/board-draw/src/components/tools-panel/ShapeTools.tsx
index 83b890fc09..eb2fb5c564 100644
--- a/libs/components/board-draw/src/components/tools-panel/ShapeTools.tsx
+++ b/libs/components/board-draw/src/components/tools-panel/ShapeTools.tsx
@@ -1,22 +1,22 @@
-import { useState, useEffect } from 'react';
import {
- ShapeIcon,
- RectangleIcon,
- EllipseIcon,
- TriangleIcon,
- PolygonIcon,
- StarIcon,
ArrowIcon,
+ EllipseIcon,
+ PolygonIcon,
+ RectangleIcon,
+ ShapeIcon,
+ StarIcon,
+ TriangleIcon,
} from '@toeverything/components/icons';
import {
- Tooltip,
- Popover,
IconButton,
+ Popover,
styled,
+ Tooltip,
} from '@toeverything/components/ui';
+import { useEffect, useState } from 'react';
-import { TDSnapshot, TDShapeType } from '@toeverything/components/board-types';
import { TldrawApp } from '@toeverything/components/board-state';
+import { TDShapeType, TDSnapshot } from '@toeverything/components/board-types';
export type ShapeTypes =
| TDShapeType.Rectangle
diff --git a/libs/components/board-draw/src/components/tools-panel/ToolsPanel.tsx b/libs/components/board-draw/src/components/tools-panel/ToolsPanel.tsx
index f518f7bc0f..f659fdff1c 100644
--- a/libs/components/board-draw/src/components/tools-panel/ToolsPanel.tsx
+++ b/libs/components/board-draw/src/components/tools-panel/ToolsPanel.tsx
@@ -1,35 +1,35 @@
-import style9 from 'style9';
import {
+ EraserIcon,
+ EraserIconProps,
+ FrameIcon,
+ HandToolIcon,
+ HandToolIconProps,
+ SelectIcon,
+ SelectIconProps,
+ TextIcon,
+ TextIconProps,
+} from '@toeverything/components/icons';
+import {
+ IconButton,
+ PopoverContainer,
// MuiIconButton as IconButton,
// MuiTooltip as Tooltip,
Tooltip,
- PopoverContainer,
- IconButton,
useTheme,
} from '@toeverything/components/ui';
-import {
- FrameIcon,
- HandToolIcon,
- SelectIcon,
- TextIcon,
- EraserIcon,
- SelectIconProps,
- EraserIconProps,
- HandToolIconProps,
- TextIconProps,
-} from '@toeverything/components/icons';
+import style9 from 'style9';
+import { TldrawApp } from '@toeverything/components/board-state';
import {
- TDSnapshot,
TDShapeType,
+ TDSnapshot,
TDToolType,
} from '@toeverything/components/board-types';
-import { TldrawApp } from '@toeverything/components/board-state';
-import { ShapeTools } from './ShapeTools';
-import { PenTools } from './pen-tools';
+import { ComponentType } from 'react';
import { LineTools } from './LineTools';
-import { ComponentType, Component } from 'react';
+import { PenTools } from './pen-tools';
+import { ShapeTools } from './ShapeTools';
const activeToolSelector = (s: TDSnapshot) => s.appState.activeTool;
const toolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked;
@@ -52,8 +52,8 @@ const tools: Array<{
{ type: 'frame', label: 'Frame', tooltip: 'Frame', icon: FrameIcon },
{
type: TDShapeType.Editor,
- label: 'Text',
- tooltip: 'Text',
+ label: 'Text Block',
+ tooltip: 'Text Block',
icon: TextIcon,
},
{ type: 'shapes', component: ShapeTools },
@@ -61,9 +61,9 @@ const tools: Array<{
{ type: 'Connector', component: LineTools },
// { type: 'erase', label: 'Erase', tooltip: 'Erase', icon: EraseIcon },
{
- type: TDShapeType.HandDraw,
- label: 'HandDraw',
- tooltip: 'HandDraw',
+ type: TDShapeType.HandDrag,
+ label: 'Hand Drag',
+ tooltip: 'Hand Drag',
icon: HandToolIcon,
},
{
diff --git a/libs/components/board-draw/src/components/tools-panel/pen-tools/Pen.tsx b/libs/components/board-draw/src/components/tools-panel/pen-tools/Pen.tsx
index 119e464e0f..bdddb055a4 100644
--- a/libs/components/board-draw/src/components/tools-panel/pen-tools/Pen.tsx
+++ b/libs/components/board-draw/src/components/tools-panel/pen-tools/Pen.tsx
@@ -1,5 +1,5 @@
+import { IconButton, styled, Tooltip } from '@toeverything/components/ui';
import type { ReactNode } from 'react';
-import { Tooltip, styled, IconButton } from '@toeverything/components/ui';
interface PenProps {
name: string;
diff --git a/libs/components/board-draw/src/components/tools-panel/pen-tools/PenTools.tsx b/libs/components/board-draw/src/components/tools-panel/pen-tools/PenTools.tsx
index 5da177f152..0536acfce1 100644
--- a/libs/components/board-draw/src/components/tools-panel/pen-tools/PenTools.tsx
+++ b/libs/components/board-draw/src/components/tools-panel/pen-tools/PenTools.tsx
@@ -1,19 +1,18 @@
-import { ReactElement, type CSSProperties } from 'react';
-import style9 from 'style9';
-import {
- MuiDivider as Divider,
- Popover,
- Tooltip,
- IconButton,
- styled,
-} from '@toeverything/components/ui';
-import { TDShapeType, TDToolType } from '@toeverything/components/board-types';
import { TldrawApp } from '@toeverything/components/board-state';
+import { TDShapeType, TDToolType } from '@toeverything/components/board-types';
import {
- PencilDuotoneIcon,
HighlighterDuotoneIcon,
LaserPenDuotoneIcon,
+ PencilDuotoneIcon,
} from '@toeverything/components/icons';
+import {
+ IconButton,
+ MuiDivider as Divider,
+ Popover,
+ styled,
+ Tooltip,
+} from '@toeverything/components/ui';
+import { ReactElement, type CSSProperties } from 'react';
import { Palette } from '../../palette';
import { Pen } from './Pen';
diff --git a/libs/components/board-draw/src/components/zoom-bar/ZoomBar.tsx b/libs/components/board-draw/src/components/zoom-bar/ZoomBar.tsx
index 66b11ab1c6..c3d1856d9f 100644
--- a/libs/components/board-draw/src/components/zoom-bar/ZoomBar.tsx
+++ b/libs/components/board-draw/src/components/zoom-bar/ZoomBar.tsx
@@ -1,14 +1,14 @@
+import AddIcon from '@mui/icons-material/Add';
+import RemoveIcon from '@mui/icons-material/Remove';
+import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore';
import {
- MuiIconButton as IconButton,
MuiButton as Button,
+ MuiIconButton as IconButton,
styled,
} from '@toeverything/components/ui';
-import RemoveIcon from '@mui/icons-material/Remove';
-import AddIcon from '@mui/icons-material/Add';
-import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore';
-import { useTldrawApp } from '../../hooks';
import { TDSnapshot } from '@toeverything/components/board-types';
+import { useTldrawApp } from '../../hooks';
import { MiniMap } from './mini-map';
diff --git a/libs/components/board-draw/src/components/zoom-bar/mini-map/MiniMap.tsx b/libs/components/board-draw/src/components/zoom-bar/mini-map/MiniMap.tsx
index 40ffbd9d34..dbe107660c 100644
--- a/libs/components/board-draw/src/components/zoom-bar/mini-map/MiniMap.tsx
+++ b/libs/components/board-draw/src/components/zoom-bar/mini-map/MiniMap.tsx
@@ -4,9 +4,9 @@ import { TLDR } from '@toeverything/components/board-state';
import { styled } from '@toeverything/components/ui';
import { useTldrawApp } from '../../../hooks';
+import { getViewportBound, processBound } from './bounds';
import { SimplifiedShape } from './SimplifiedShape';
import { Viewport } from './Viewport';
-import { processBound, getViewportBound } from './bounds';
const MINI_MAP_WIDTH = 150;
const MINI_MAP_HEIGHT = 100;
diff --git a/libs/components/board-draw/src/components/zoom-bar/mini-map/SimplifiedShape.tsx b/libs/components/board-draw/src/components/zoom-bar/mini-map/SimplifiedShape.tsx
index ac8101956a..c35b148c2b 100644
--- a/libs/components/board-draw/src/components/zoom-bar/mini-map/SimplifiedShape.tsx
+++ b/libs/components/board-draw/src/components/zoom-bar/mini-map/SimplifiedShape.tsx
@@ -1,6 +1,6 @@
-import type { CSSProperties } from 'react';
import type { TLBounds } from '@tldraw/core';
import { styled } from '@toeverything/components/ui';
+import type { CSSProperties } from 'react';
interface SimplifiedShapeProps extends TLBounds {
onClick?: () => void;
diff --git a/libs/components/board-draw/src/components/zoom-bar/mini-map/Viewport.tsx b/libs/components/board-draw/src/components/zoom-bar/mini-map/Viewport.tsx
index 2db0588ba5..5b4283cb07 100644
--- a/libs/components/board-draw/src/components/zoom-bar/mini-map/Viewport.tsx
+++ b/libs/components/board-draw/src/components/zoom-bar/mini-map/Viewport.tsx
@@ -1,8 +1,8 @@
-import type { CSSProperties, PointerEventHandler } from 'react';
-import { useState, useRef } from 'react';
import type { TLBounds } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import { styled, alpha } from '@toeverything/components/ui';
+import { alpha, styled } from '@toeverything/components/ui';
+import type { CSSProperties, PointerEventHandler } from 'react';
+import { useRef, useState } from 'react';
interface ViewportProps extends TLBounds {
onPan?: (delta: [number, number]) => void;
diff --git a/libs/components/board-draw/src/hooks/index.ts b/libs/components/board-draw/src/hooks/index.ts
index 26a3f2ad7c..9b62682530 100644
--- a/libs/components/board-draw/src/hooks/index.ts
+++ b/libs/components/board-draw/src/hooks/index.ts
@@ -1,6 +1,6 @@
+export * from './use-file-system-handlers';
export * from './use-keyboard-shortcuts';
-export * from './use-tldraw-app';
// export * from './useTheme';
export * from './use-stylesheet';
-export * from './use-file-system-handlers';
+export * from './use-tldraw-app';
// export * from './useFileSystem';
diff --git a/libs/components/board-draw/src/hooks/use-keyboard-shortcuts.tsx b/libs/components/board-draw/src/hooks/use-keyboard-shortcuts.tsx
index e553bc3d5c..b52de15e37 100644
--- a/libs/components/board-draw/src/hooks/use-keyboard-shortcuts.tsx
+++ b/libs/components/board-draw/src/hooks/use-keyboard-shortcuts.tsx
@@ -1,8 +1,8 @@
+import { AlignStyle, TDShapeType } from '@toeverything/components/board-types';
import * as React from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
-import { AlignStyle, TDShapeType } from '@toeverything/components/board-types';
-import { useTldrawApp } from './use-tldraw-app';
import { useFileSystemHandlers } from './use-file-system-handlers';
+import { useTldrawApp } from './use-tldraw-app';
export function useKeyboardShortcuts(ref: React.RefObject) {
const app = useTldrawApp();
diff --git a/libs/components/board-draw/src/hooks/use-tldraw-app.ts b/libs/components/board-draw/src/hooks/use-tldraw-app.ts
index b825478034..c96a076a57 100644
--- a/libs/components/board-draw/src/hooks/use-tldraw-app.ts
+++ b/libs/components/board-draw/src/hooks/use-tldraw-app.ts
@@ -1,5 +1,5 @@
-import * as React from 'react';
import type { TldrawApp } from '@toeverything/components/board-state';
+import * as React from 'react';
export const TldrawContext = React.createContext({} as TldrawApp);
diff --git a/libs/components/board-draw/src/index.ts b/libs/components/board-draw/src/index.ts
index 69704e7d8c..aeaf8da126 100644
--- a/libs/components/board-draw/src/index.ts
+++ b/libs/components/board-draw/src/index.ts
@@ -1,2 +1,2 @@
-export { Tldraw } from './TlDraw';
export { useTldrawApp } from './hooks';
+export { Tldraw } from './TlDraw';
diff --git a/libs/components/board-sessions/src/arrow-session.ts b/libs/components/board-sessions/src/arrow-session.ts
index 7c2277df0c..bb334c4ee4 100644
--- a/libs/components/board-sessions/src/arrow-session.ts
+++ b/libs/components/board-sessions/src/arrow-session.ts
@@ -1,21 +1,21 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
+import { Utils } from '@tldraw/core';
+import { Vec } from '@tldraw/vec';
+import { shapeUtils } from '@toeverything/components/board-shapes';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { deepCopy, TLDR } from '@toeverything/components/board-state';
import {
ArrowBinding,
ArrowShape,
- TDShape,
- TDBinding,
- TDStatus,
SessionType,
+ TDBinding,
+ TDShape,
TDShapeType,
- TldrawPatch,
+ TDStatus,
TldrawCommand,
+ TldrawPatch,
} from '@toeverything/components/board-types';
-import { Vec } from '@tldraw/vec';
-import { TLDR, deepCopy } from '@toeverything/components/board-state';
-import { shapeUtils } from '@toeverything/components/board-shapes';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
-import { Utils } from '@tldraw/core';
export class ArrowSession extends BaseSession {
type = SessionType.Arrow;
diff --git a/libs/components/board-sessions/src/base-session.ts b/libs/components/board-sessions/src/base-session.ts
index 397b8587a3..a14fa663f6 100644
--- a/libs/components/board-sessions/src/base-session.ts
+++ b/libs/components/board-sessions/src/base-session.ts
@@ -1,5 +1,5 @@
-import { BaseSessionType } from '@toeverything/components/board-types';
import type { TldrawApp } from '@toeverything/components/board-state';
+import { BaseSessionType } from '@toeverything/components/board-types';
export abstract class BaseSession extends BaseSessionType {
app: TldrawApp;
diff --git a/libs/components/board-sessions/src/brush-session.ts b/libs/components/board-sessions/src/brush-session.ts
index dfb10a6a95..981e2149d0 100644
--- a/libs/components/board-sessions/src/brush-session.ts
+++ b/libs/components/board-sessions/src/brush-session.ts
@@ -1,11 +1,11 @@
import { TLBounds, Utils } from '@tldraw/core';
+import type { TldrawApp } from '@toeverything/components/board-state';
import {
SessionType,
- TldrawPatch,
TDStatus,
TldrawCommand,
+ TldrawPatch,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
export class BrushSession extends BaseSession {
diff --git a/libs/components/board-sessions/src/draw-session.ts b/libs/components/board-sessions/src/draw-session.ts
index c932ae3de0..1cec1392a1 100644
--- a/libs/components/board-sessions/src/draw-session.ts
+++ b/libs/components/board-sessions/src/draw-session.ts
@@ -1,13 +1,13 @@
import { Utils } from '@tldraw/core';
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
import {
+ DrawShape,
SessionType,
TDStatus,
- TldrawPatch,
TldrawCommand,
- DrawShape,
+ TldrawPatch,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
export class DrawSession extends BaseSession {
diff --git a/libs/components/board-sessions/src/erase-session.ts b/libs/components/board-sessions/src/erase-session.ts
index 41040d4303..2f7121dd12 100644
--- a/libs/components/board-sessions/src/erase-session.ts
+++ b/libs/components/board-sessions/src/erase-session.ts
@@ -1,14 +1,14 @@
import { Vec } from '@tldraw/vec';
-import {
- SessionType,
- TDStatus,
- TDShape,
- PagePartial,
- TDBinding,
- TldrawPatch,
- TldrawCommand,
-} from '@toeverything/components/board-types';
import type { TldrawApp } from '@toeverything/components/board-state';
+import {
+ PagePartial,
+ SessionType,
+ TDBinding,
+ TDShape,
+ TDStatus,
+ TldrawCommand,
+ TldrawPatch,
+} from '@toeverything/components/board-types';
import { BaseSession } from './base-session';
export class EraseSession extends BaseSession {
diff --git a/libs/components/board-sessions/src/grid-session.ts b/libs/components/board-sessions/src/grid-session.ts
index 6460d087d4..848faead3d 100644
--- a/libs/components/board-sessions/src/grid-session.ts
+++ b/libs/components/board-sessions/src/grid-session.ts
@@ -1,17 +1,16 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
-import { TLPageState, TLBounds, Utils } from '@tldraw/core';
+import { TLBounds, TLPageState, Utils } from '@tldraw/core';
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
import {
Patch,
+ SessionType,
TDShape,
TDStatus,
- SessionType,
- TDShapeType,
- TldrawPatch,
TldrawCommand,
+ TldrawPatch,
} from '@toeverything/components/board-types';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
export class GridSession extends BaseSession {
type = SessionType.Grid;
diff --git a/libs/components/board-sessions/src/handle-session.ts b/libs/components/board-sessions/src/handle-session.ts
index 72af0591ff..6140590796 100644
--- a/libs/components/board-sessions/src/handle-session.ts
+++ b/libs/components/board-sessions/src/handle-session.ts
@@ -1,14 +1,14 @@
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
SessionType,
ShapesWithProp,
+ TDStatus,
TldrawCommand,
TldrawPatch,
- TDStatus,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
export class HandleSession extends BaseSession {
type = SessionType.Handle;
diff --git a/libs/components/board-sessions/src/index.ts b/libs/components/board-sessions/src/index.ts
index 6d6d94fa81..86a847fa69 100644
--- a/libs/components/board-sessions/src/index.ts
+++ b/libs/components/board-sessions/src/index.ts
@@ -2,14 +2,14 @@ import { ExceptFirst, SessionType } from '@toeverything/components/board-types';
import { ArrowSession } from './arrow-session';
import { BrushSession } from './brush-session';
import { DrawSession } from './draw-session';
+import { EraseSession } from './erase-session';
+import { GridSession } from './grid-session';
import { HandleSession } from './handle-session';
+import { LaserSession } from './laser-session';
import { RotateSession } from './rotate-session';
import { TransformSession } from './transform-session';
import { TransformSingleSession } from './transform-single-session';
import { TranslateSession } from './translate-session';
-import { EraseSession } from './erase-session';
-import { GridSession } from './grid-session';
-import { LaserSession } from './laser-session';
export type TldrawSession =
| ArrowSession
diff --git a/libs/components/board-sessions/src/laser-session.ts b/libs/components/board-sessions/src/laser-session.ts
index 8e2b5c62d1..ba1c1d5b86 100644
--- a/libs/components/board-sessions/src/laser-session.ts
+++ b/libs/components/board-sessions/src/laser-session.ts
@@ -1,11 +1,11 @@
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
import {
SessionType,
TDStatus,
- TldrawPatch,
TldrawCommand,
+ TldrawPatch,
} from '@toeverything/components/board-types';
-import type { TldrawApp } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
export class LaserSession extends BaseSession {
type = SessionType.Draw;
diff --git a/libs/components/board-sessions/src/rotate-session.ts b/libs/components/board-sessions/src/rotate-session.ts
index 2de48ed120..93c6bad294 100644
--- a/libs/components/board-sessions/src/rotate-session.ts
+++ b/libs/components/board-sessions/src/rotate-session.ts
@@ -1,16 +1,16 @@
import { Utils } from '@tldraw/core';
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
SessionType,
+ TDShape,
+ TDShapeType,
+ TDStatus,
TldrawCommand,
TldrawPatch,
- TDShape,
- TDStatus,
- TDShapeType,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
export class RotateSession extends BaseSession {
type = SessionType.Rotate;
diff --git a/libs/components/board-sessions/src/transform-session.ts b/libs/components/board-sessions/src/transform-session.ts
index 2caab14095..966e9e8bda 100644
--- a/libs/components/board-sessions/src/transform-session.ts
+++ b/libs/components/board-sessions/src/transform-session.ts
@@ -1,18 +1,18 @@
+import type { TLBoundsWithCenter, TLSnapLine } from '@tldraw/core';
import { TLBounds, TLBoundsCorner, TLBoundsEdge, Utils } from '@tldraw/core';
import { Vec } from '@tldraw/vec';
-import type { TLSnapLine, TLBoundsWithCenter } from '@tldraw/core';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
SessionType,
- TldrawCommand,
- TldrawPatch,
- TDShape,
- TDStatus,
SLOW_SPEED,
SNAP_DISTANCE,
+ TDShape,
+ TDStatus,
+ TldrawCommand,
+ TldrawPatch,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
type SnapInfo =
| {
diff --git a/libs/components/board-sessions/src/transform-single-session.ts b/libs/components/board-sessions/src/transform-single-session.ts
index 8f7711b3e2..483c0d0cd1 100644
--- a/libs/components/board-sessions/src/transform-single-session.ts
+++ b/libs/components/board-sessions/src/transform-single-session.ts
@@ -1,24 +1,24 @@
import {
- TLBoundsCorner,
- TLSnapLine,
- TLBoundsEdge,
- Utils,
- TLBoundsWithCenter,
TLBounds,
+ TLBoundsCorner,
+ TLBoundsEdge,
+ TLBoundsWithCenter,
+ TLSnapLine,
+ Utils,
} from '@tldraw/core';
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
SessionType,
- TldrawCommand,
- TldrawPatch,
- TDShape,
- TDStatus,
SLOW_SPEED,
SNAP_DISTANCE,
+ TDShape,
+ TDStatus,
+ TldrawCommand,
+ TldrawPatch,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
type SnapInfo =
| {
diff --git a/libs/components/board-sessions/src/translate-label-session.ts b/libs/components/board-sessions/src/translate-label-session.ts
index 0fea7ed92c..f490fd0b88 100644
--- a/libs/components/board-sessions/src/translate-label-session.ts
+++ b/libs/components/board-sessions/src/translate-label-session.ts
@@ -1,17 +1,17 @@
+import type { TLBounds } from '@tldraw/core';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
+ ArrowShape,
+ EllipseShape,
+ RectangleShape,
SessionType,
+ TDStatus,
TldrawCommand,
TldrawPatch,
- TDStatus,
- RectangleShape,
TriangleShape,
- EllipseShape,
- ArrowShape,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
-import type { TLBounds } from '@tldraw/core';
export class TranslateLabelSession extends BaseSession {
type = SessionType.Handle;
diff --git a/libs/components/board-sessions/src/translate-session.ts b/libs/components/board-sessions/src/translate-session.ts
index 6019e05594..59f227d866 100644
--- a/libs/components/board-sessions/src/translate-session.ts
+++ b/libs/components/board-sessions/src/translate-session.ts
@@ -1,30 +1,30 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import {
- TLPageState,
- Utils,
- TLBoundsWithCenter,
- TLSnapLine,
TLBounds,
+ TLBoundsWithCenter,
+ TLPageState,
+ TLSnapLine,
+ Utils,
} from '@tldraw/core';
import { Vec } from '@tldraw/vec';
+import type { TldrawApp } from '@toeverything/components/board-state';
+import { TLDR } from '@toeverything/components/board-state';
import {
- TDShape,
- TDBinding,
- TldrawCommand,
- TDStatus,
- ArrowShape,
- Patch,
- GroupShape,
- SessionType,
ArrowBinding,
- TldrawPatch,
- TDShapeType,
+ ArrowShape,
+ GroupShape,
+ Patch,
+ SessionType,
SLOW_SPEED,
SNAP_DISTANCE,
+ TDBinding,
+ TDShape,
+ TDShapeType,
+ TDStatus,
+ TldrawCommand,
+ TldrawPatch,
} from '@toeverything/components/board-types';
-import { TLDR } from '@toeverything/components/board-state';
import { BaseSession } from './base-session';
-import type { TldrawApp } from '@toeverything/components/board-state';
type CloneInfo =
| {
@@ -111,7 +111,8 @@ export class TranslateSession extends BaseSession {
Utils.boundsContain(
TLDR.get_bounds(shap),
TLDR.get_bounds(shapItem)
- )
+ ) &&
+ !shapItem.isLocked
) {
selectedShapes.push(shapItem);
}
diff --git a/libs/components/board-shapes/src/TDShapeUtil.tsx b/libs/components/board-shapes/src/TDShapeUtil.tsx
index 2c7afe480e..bb8da6905e 100644
--- a/libs/components/board-shapes/src/TDShapeUtil.tsx
+++ b/libs/components/board-shapes/src/TDShapeUtil.tsx
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
-import { Utils, TLShapeUtil } from '@tldraw/core';
-import type { TLPointerInfo, TLBounds } from '@tldraw/core';
+import type { TLBounds, TLPointerInfo } from '@tldraw/core';
+import { TLShapeUtil, Utils } from '@tldraw/core';
import {
intersectLineSegmentBounds,
intersectLineSegmentPolyline,
@@ -15,9 +15,9 @@ import type {
} from '@toeverything/components/board-types';
import { BINDING_DISTANCE } from '@toeverything/components/board-types';
import { createRef } from 'react';
-import { getTextSvgElement } from './shared/get-text-svg-element';
-import { getTextLabelSize } from './shared/get-text-size';
import { getFontStyle, getShapeStyle } from './shared';
+import { getTextLabelSize } from './shared/get-text-size';
+import { getTextSvgElement } from './shared/get-text-svg-element';
export abstract class TDShapeUtil<
T extends TDShape,
diff --git a/libs/components/board-shapes/src/arrow-util/arrow-helpers.ts b/libs/components/board-shapes/src/arrow-util/arrow-helpers.ts
index 9b3b747870..47916eeb63 100644
--- a/libs/components/board-shapes/src/arrow-util/arrow-helpers.ts
+++ b/libs/components/board-shapes/src/arrow-util/arrow-helpers.ts
@@ -4,14 +4,14 @@ import {
intersectCircleLineSegment,
} from '@tldraw/intersect';
import Vec from '@tldraw/vec';
-import getStroke from 'perfect-freehand';
-import { EASINGS } from '@toeverything/components/board-types';
-import { getShapeStyle } from '../shared/shape-styles';
import type {
ArrowShape,
Decoration,
ShapeStyles,
} from '@toeverything/components/board-types';
+import { EASINGS } from '@toeverything/components/board-types';
+import getStroke from 'perfect-freehand';
+import { getShapeStyle } from '../shared/shape-styles';
export function getArrowArcPath(
start: number[],
diff --git a/libs/components/board-shapes/src/arrow-util/arrow-util.tsx b/libs/components/board-shapes/src/arrow-util/arrow-util.tsx
index 321ef27d2e..42045918f4 100644
--- a/libs/components/board-shapes/src/arrow-util/arrow-util.tsx
+++ b/libs/components/board-shapes/src/arrow-util/arrow-util.tsx
@@ -1,22 +1,30 @@
-import * as React from 'react';
-import { Utils, TLBounds, SVGContainer } from '@tldraw/core';
-import { Vec } from '@tldraw/vec';
-import { defaultStyle } from '../shared/shape-styles';
-import {
- ArrowShape,
- TransformInfo,
- Decoration,
- TDShapeType,
- DashStyle,
- TDMeta,
- GHOSTED_OPACITY,
-} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
+import { SVGContainer, TLBounds, Utils } from '@tldraw/core';
import {
intersectArcBounds,
intersectLineSegmentBounds,
intersectLineSegmentLineSegment,
} from '@tldraw/intersect';
+import { Vec } from '@tldraw/vec';
+import {
+ ArrowShape,
+ DashStyle,
+ Decoration,
+ GHOSTED_OPACITY,
+ TDMeta,
+ TDShapeType,
+ TransformInfo,
+} from '@toeverything/components/board-types';
+import { styled } from '@toeverything/components/ui';
+import * as React from 'react';
+import {
+ getFontStyle,
+ getShapeStyle,
+ getTextLabelSize,
+ LabelMask,
+ TextLabel,
+} from '../shared';
+import { defaultStyle } from '../shared/shape-styles';
+import { TDShapeUtil } from '../TDShapeUtil';
import {
getArcLength,
getArcPoints,
@@ -25,16 +33,8 @@ import {
getCtp,
isAngleBetween,
} from './arrow-helpers';
-import { styled } from '@toeverything/components/ui';
-import {
- TextLabel,
- getFontStyle,
- getShapeStyle,
- getTextLabelSize,
- LabelMask,
-} from '../shared';
-import { StraightArrow } from './components/straight-arrow';
import { CurvedArrow } from './components/curved-arrow';
+import { StraightArrow } from './components/straight-arrow';
type T = ArrowShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/arrow-util/components/arrow-head.tsx b/libs/components/board-shapes/src/arrow-util/components/arrow-head.tsx
index 18fa47fecb..e574e500d5 100644
--- a/libs/components/board-shapes/src/arrow-util/components/arrow-head.tsx
+++ b/libs/components/board-shapes/src/arrow-util/components/arrow-head.tsx
@@ -1,5 +1,3 @@
-import * as React from 'react';
-
export interface ArrowheadProps {
left: number[];
middle: number[];
diff --git a/libs/components/board-shapes/src/arrow-util/components/curved-arrow.tsx b/libs/components/board-shapes/src/arrow-util/components/curved-arrow.tsx
index 5fc8056cf3..9eed25c430 100644
--- a/libs/components/board-shapes/src/arrow-util/components/curved-arrow.tsx
+++ b/libs/components/board-shapes/src/arrow-util/components/curved-arrow.tsx
@@ -1,12 +1,12 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import * as React from 'react';
-import { EASINGS } from '@toeverything/components/board-types';
-import { getShapeStyle } from '../../shared';
import type {
Decoration,
ShapeStyles,
} from '@toeverything/components/board-types';
+import { EASINGS } from '@toeverything/components/board-types';
+import * as React from 'react';
+import { getShapeStyle } from '../../shared';
import {
getArcLength,
getArrowArcPath,
diff --git a/libs/components/board-shapes/src/arrow-util/components/straight-arrow.tsx b/libs/components/board-shapes/src/arrow-util/components/straight-arrow.tsx
index 5414574a92..20d0d3c93f 100644
--- a/libs/components/board-shapes/src/arrow-util/components/straight-arrow.tsx
+++ b/libs/components/board-shapes/src/arrow-util/components/straight-arrow.tsx
@@ -1,11 +1,11 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import * as React from 'react';
-import { getShapeStyle } from '../../shared';
import type {
Decoration,
ShapeStyles,
} from '@toeverything/components/board-types';
+import * as React from 'react';
+import { getShapeStyle } from '../../shared';
import {
getStraightArrowHeadPoints,
renderFreehandArrowShaft,
diff --git a/libs/components/board-shapes/src/draw-util/DrawUtil.tsx b/libs/components/board-shapes/src/draw-util/DrawUtil.tsx
index 9f78d0aa2c..db36aa0ef3 100644
--- a/libs/components/board-shapes/src/draw-util/DrawUtil.tsx
+++ b/libs/components/board-shapes/src/draw-util/DrawUtil.tsx
@@ -1,22 +1,22 @@
-import * as React from 'react';
-import { Utils, SVGContainer, TLBounds } from '@tldraw/core';
-import { Vec } from '@tldraw/vec';
-import { defaultStyle, getShapeStyle } from '../shared/shape-styles';
-import {
- DrawShape,
- DashStyle,
- TDShapeType,
- TransformInfo,
- TDMeta,
- GHOSTED_OPACITY,
-} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
+import { SVGContainer, TLBounds, Utils } from '@tldraw/core';
import {
intersectBoundsBounds,
intersectBoundsPolyline,
intersectLineSegmentBounds,
intersectLineSegmentLineSegment,
} from '@tldraw/intersect';
+import { Vec } from '@tldraw/vec';
+import {
+ DashStyle,
+ DrawShape,
+ GHOSTED_OPACITY,
+ TDMeta,
+ TDShapeType,
+ TransformInfo,
+} from '@toeverything/components/board-types';
+import * as React from 'react';
+import { defaultStyle, getShapeStyle } from '../shared/shape-styles';
+import { TDShapeUtil } from '../TDShapeUtil';
import {
getDrawStrokePathTDSnapshot,
getFillPath,
diff --git a/libs/components/board-shapes/src/draw-util/draw-helpers.ts b/libs/components/board-shapes/src/draw-util/draw-helpers.ts
index 58a59db027..f0cb0d434a 100644
--- a/libs/components/board-shapes/src/draw-util/draw-helpers.ts
+++ b/libs/components/board-shapes/src/draw-util/draw-helpers.ts
@@ -1,11 +1,11 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
+import type { DrawShape } from '@toeverything/components/board-types';
import {
getStrokeOutlinePoints,
getStrokePoints,
StrokeOptions,
} from 'perfect-freehand';
-import type { DrawShape } from '@toeverything/components/board-types';
import { getShapeStyle } from '../shared/shape-styles';
const simulatePressureSettings: StrokeOptions = {
diff --git a/libs/components/board-shapes/src/editor-util/EditorUtil.tsx b/libs/components/board-shapes/src/editor-util/EditorUtil.tsx
index 2f1820e0c3..805ada0623 100644
--- a/libs/components/board-shapes/src/editor-util/EditorUtil.tsx
+++ b/libs/components/board-shapes/src/editor-util/EditorUtil.tsx
@@ -1,24 +1,25 @@
/* eslint-disable no-restricted-syntax */
-import { useRef, useCallback, useEffect, memo } from 'react';
-import type { SyntheticEvent } from 'react';
-import { Utils, HTMLContainer, TLBounds } from '@tldraw/core';
+import { HTMLContainer, TLBounds, Utils } from '@tldraw/core';
+import { Vec } from '@tldraw/vec';
+import { AffineEditor } from '@toeverything/components/affine-editor';
import {
EditorShape,
TDMeta,
TDShapeType,
TransformInfo,
} from '@toeverything/components/board-types';
+import type { BlockEditor } from '@toeverything/components/editor-core';
+import { MIN_PAGE_WIDTH } from '@toeverything/components/editor-core';
+import { styled } from '@toeverything/components/ui';
+import type { MouseEvent, SyntheticEvent } from 'react';
+import { memo, useCallback, useEffect, useRef } from 'react';
import {
defaultTextStyle,
getBoundsRectangle,
getTextSvgElement,
} from '../shared';
-import { TDShapeUtil } from '../TDShapeUtil';
import { getShapeStyle } from '../shared/shape-styles';
-import { styled } from '@toeverything/components/ui';
-import { Vec } from '@tldraw/vec';
-import { AffineEditor } from '@toeverything/components/affine-editor';
-import { MIN_PAGE_WIDTH } from '@toeverything/components/editor-core';
+import { TDShapeUtil } from '../TDShapeUtil';
const MemoAffineEditor = memo(AffineEditor, (prev, next) => {
return (
prev.workspace === next.workspace &&
@@ -66,6 +67,7 @@ export class EditorUtil extends TDShapeUtil {
Component = TDShapeUtil.Component(
({ shape, meta: { app }, events, isEditing, onShapeChange }, ref) => {
const containerRef = useRef();
+ const editorRef = useRef();
const {
workspace,
rootBlockId,
@@ -135,6 +137,27 @@ export class EditorUtil extends TDShapeUtil {
}
}, [app, state, shape.id, editingText, editingId]);
+ useEffect(() => {
+ (async () => {
+ if (isEditing) {
+ const lastBlock =
+ await editorRef.current.getLastBlock();
+ editorRef.current.selectionManager.activeNodeByNodeId(
+ lastBlock.id
+ );
+ }
+ })();
+ }, [isEditing]);
+
+ const onMouseDown = useCallback(
+ (e: MouseEvent) => {
+ if (e.detail === 2) {
+ app.setEditingText(shape.id);
+ }
+ },
+ [app, shape.id]
+ );
+
return (
{
onPointerDown={stopPropagation}
onMouseEnter={activateIfEditing}
onDragEnter={activateIfEditing}
+ onMouseDown={onMouseDown}
>
{editingText ? null : }
diff --git a/libs/components/board-shapes/src/ellipse-util/EllipseUtil.tsx b/libs/components/board-shapes/src/ellipse-util/EllipseUtil.tsx
index 4cbd2cd897..1a25760094 100644
--- a/libs/components/board-shapes/src/ellipse-util/EllipseUtil.tsx
+++ b/libs/components/board-shapes/src/ellipse-util/EllipseUtil.tsx
@@ -1,32 +1,32 @@
-import * as React from 'react';
-import { Utils, SVGContainer, TLBounds } from '@tldraw/core';
-import { Vec } from '@tldraw/vec';
-import {
- defaultStyle,
- getShapeStyle,
- getFontStyle,
- TextLabel,
-} from '../shared';
-import {
- EllipseShape,
- DashStyle,
- TDShapeType,
- TDShape,
- TransformInfo,
- TDMeta,
- GHOSTED_OPACITY,
- LABEL_POINT,
-} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
+import { SVGContainer, TLBounds, Utils } from '@tldraw/core';
import {
intersectEllipseBounds,
intersectLineSegmentEllipse,
intersectRayEllipse,
} from '@tldraw/intersect';
-import { getEllipseIndicatorPath } from './ellipse-helpers';
-import { DrawEllipse } from './components/DrawEllipse';
-import { DashedEllipse } from './components/DashedEllipse';
+import { Vec } from '@tldraw/vec';
+import {
+ DashStyle,
+ EllipseShape,
+ GHOSTED_OPACITY,
+ LABEL_POINT,
+ TDMeta,
+ TDShape,
+ TDShapeType,
+ TransformInfo,
+} from '@toeverything/components/board-types';
import { styled } from '@toeverything/components/ui';
+import * as React from 'react';
+import {
+ defaultStyle,
+ getFontStyle,
+ getShapeStyle,
+ TextLabel,
+} from '../shared';
+import { TDShapeUtil } from '../TDShapeUtil';
+import { DashedEllipse } from './components/DashedEllipse';
+import { DrawEllipse } from './components/DrawEllipse';
+import { getEllipseIndicatorPath } from './ellipse-helpers';
type T = EllipseShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/ellipse-util/components/DashedEllipse.tsx b/libs/components/board-shapes/src/ellipse-util/components/DashedEllipse.tsx
index 23dbaf5247..e24c017628 100644
--- a/libs/components/board-shapes/src/ellipse-util/components/DashedEllipse.tsx
+++ b/libs/components/board-shapes/src/ellipse-util/components/DashedEllipse.tsx
@@ -1,6 +1,6 @@
-import * as React from 'react';
import { Utils } from '@tldraw/core';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import * as React from 'react';
import { getShapeStyle } from '../../shared';
interface EllipseSvgProps {
diff --git a/libs/components/board-shapes/src/ellipse-util/components/DrawEllipse.tsx b/libs/components/board-shapes/src/ellipse-util/components/DrawEllipse.tsx
index e768679512..7d1f9f4e7b 100644
--- a/libs/components/board-shapes/src/ellipse-util/components/DrawEllipse.tsx
+++ b/libs/components/board-shapes/src/ellipse-util/components/DrawEllipse.tsx
@@ -1,6 +1,6 @@
+import type { ShapeStyles } from '@toeverything/components/board-types';
import * as React from 'react';
import { getShapeStyle } from '../../shared';
-import type { ShapeStyles } from '@toeverything/components/board-types';
import { getEllipseIndicatorPath, getEllipsePath } from '../ellipse-helpers';
interface EllipseSvgProps {
diff --git a/libs/components/board-shapes/src/ellipse-util/ellipse-helpers.ts b/libs/components/board-shapes/src/ellipse-util/ellipse-helpers.ts
index be85174b2a..dcb2dcab5e 100644
--- a/libs/components/board-shapes/src/ellipse-util/ellipse-helpers.ts
+++ b/libs/components/board-shapes/src/ellipse-util/ellipse-helpers.ts
@@ -1,7 +1,7 @@
import { Utils } from '@tldraw/core';
-import { getStrokeOutlinePoints, getStrokePoints } from 'perfect-freehand';
-import { EASINGS } from '@toeverything/components/board-types';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import { EASINGS } from '@toeverything/components/board-types';
+import { getStrokeOutlinePoints, getStrokePoints } from 'perfect-freehand';
import { getShapeStyle } from '../shared/shape-styles';
export function getEllipseStrokePoints(
diff --git a/libs/components/board-shapes/src/frame-util/FrameUtil.tsx b/libs/components/board-shapes/src/frame-util/FrameUtil.tsx
index 47fc778da7..22710dc9b7 100644
--- a/libs/components/board-shapes/src/frame-util/FrameUtil.tsx
+++ b/libs/components/board-shapes/src/frame-util/FrameUtil.tsx
@@ -1,20 +1,20 @@
/* eslint-disable no-restricted-syntax */
-import { Utils, SVGContainer } from '@tldraw/core';
+import { SVGContainer, Utils } from '@tldraw/core';
import {
FrameShape,
- TDShapeType,
TDMeta,
+ TDShapeType,
} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
+import { styled } from '@toeverything/components/ui';
import {
defaultStyle,
- getShapeStyle,
getBoundsRectangle,
+ getShapeStyle,
transformRectangle,
transformSingleRectangle,
} from '../shared';
+import { TDShapeUtil } from '../TDShapeUtil';
import { Frame } from './components/Frame';
-import { styled } from '@toeverything/components/ui';
type T = FrameShape;
type E = SVGSVGElement;
diff --git a/libs/components/board-shapes/src/frame-util/components/Frame.tsx b/libs/components/board-shapes/src/frame-util/components/Frame.tsx
index 57a6fa878a..57736495d8 100644
--- a/libs/components/board-shapes/src/frame-util/components/Frame.tsx
+++ b/libs/components/board-shapes/src/frame-util/components/Frame.tsx
@@ -1,6 +1,6 @@
-import * as React from 'react';
-import { BINDING_DISTANCE } from '@toeverything/components/board-types';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import { BINDING_DISTANCE } from '@toeverything/components/board-types';
+import * as React from 'react';
import { getShapeStyle } from '../../shared';
interface RectangleSvgProps {
diff --git a/libs/components/board-shapes/src/frame-util/components/frame-binding-indicator.tsx b/libs/components/board-shapes/src/frame-util/components/frame-binding-indicator.tsx
index 3fab0bfd74..ee349f1634 100644
--- a/libs/components/board-shapes/src/frame-util/components/frame-binding-indicator.tsx
+++ b/libs/components/board-shapes/src/frame-util/components/frame-binding-indicator.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
import { BINDING_DISTANCE } from '@toeverything/components/board-types';
interface BindingIndicatorProps {
diff --git a/libs/components/board-shapes/src/group-util/group-util.tsx b/libs/components/board-shapes/src/group-util/group-util.tsx
index f19792d340..07b8d2a6fe 100644
--- a/libs/components/board-shapes/src/group-util/group-util.tsx
+++ b/libs/components/board-shapes/src/group-util/group-util.tsx
@@ -1,15 +1,14 @@
-import * as React from 'react';
-import { styled } from '@toeverything/components/ui';
-import { Utils, SVGContainer } from '@tldraw/core';
-import { defaultStyle } from '../shared/shape-styles';
+import { SVGContainer, Utils } from '@tldraw/core';
import {
- TDShapeType,
+ GHOSTED_OPACITY,
GroupShape,
TDMeta,
- GHOSTED_OPACITY,
+ TDShapeType,
} from '@toeverything/components/board-types';
+import { styled } from '@toeverything/components/ui';
+import { commonColors, getBoundsRectangle } from '../shared';
+import { defaultStyle } from '../shared/shape-styles';
import { TDShapeUtil } from '../TDShapeUtil';
-import { getBoundsRectangle, commonColors } from '../shared';
type T = GroupShape;
type E = SVGSVGElement;
diff --git a/libs/components/board-shapes/src/hexagon-util/HexagonUtil.tsx b/libs/components/board-shapes/src/hexagon-util/HexagonUtil.tsx
index 2b0ba9921a..dd32d61056 100644
--- a/libs/components/board-shapes/src/hexagon-util/HexagonUtil.tsx
+++ b/libs/components/board-shapes/src/hexagon-util/HexagonUtil.tsx
@@ -1,36 +1,36 @@
-import * as React from 'react';
-import { Utils, SVGContainer, TLBounds } from '@tldraw/core';
-import {
- HexagonShape,
- TDShapeType,
- TDMeta,
- TDShape,
- DashStyle,
- BINDING_DISTANCE,
- GHOSTED_OPACITY,
- LABEL_POINT,
-} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
-import {
- defaultStyle,
- getBoundsRectangle,
- transformRectangle,
- transformSingleRectangle,
- getFontStyle,
- TextLabel,
- getShapeStyle,
-} from '../shared';
+import { SVGContainer, TLBounds, Utils } from '@tldraw/core';
import {
intersectBoundsPolygon,
intersectLineSegmentPolyline,
intersectRayLineSegment,
} from '@tldraw/intersect';
import Vec from '@tldraw/vec';
-import { getHexagonCentroid, getHexagonPoints } from './hexagon-helpers';
+import {
+ BINDING_DISTANCE,
+ DashStyle,
+ GHOSTED_OPACITY,
+ HexagonShape,
+ LABEL_POINT,
+ TDMeta,
+ TDShape,
+ TDShapeType,
+} from '@toeverything/components/board-types';
import { styled } from '@toeverything/components/ui';
-import { DrawHexagon } from './components/DrawHexagon';
+import * as React from 'react';
+import {
+ defaultStyle,
+ getBoundsRectangle,
+ getFontStyle,
+ getShapeStyle,
+ TextLabel,
+ transformRectangle,
+ transformSingleRectangle,
+} from '../shared';
+import { TDShapeUtil } from '../TDShapeUtil';
import { DashedHexagon } from './components/DashedHexagon';
+import { DrawHexagon } from './components/DrawHexagon';
import { HexagonBindingIndicator } from './components/HexagonBindingIndicator';
+import { getHexagonCentroid, getHexagonPoints } from './hexagon-helpers';
type T = HexagonShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/hexagon-util/components/DashedHexagon.tsx b/libs/components/board-shapes/src/hexagon-util/components/DashedHexagon.tsx
index 6a93e2ff36..4080ced2cb 100644
--- a/libs/components/board-shapes/src/hexagon-util/components/DashedHexagon.tsx
+++ b/libs/components/board-shapes/src/hexagon-util/components/DashedHexagon.tsx
@@ -1,9 +1,9 @@
-import * as React from 'react';
import { Utils } from '@tldraw/core';
+import Vec from '@tldraw/vec';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import * as React from 'react';
import { getShapeStyle } from '../../shared';
import { getHexagonPoints } from '../hexagon-helpers';
-import Vec from '@tldraw/vec';
interface HexagonSvgProps {
id: string;
diff --git a/libs/components/board-shapes/src/hexagon-util/components/DrawHexagon.tsx b/libs/components/board-shapes/src/hexagon-util/components/DrawHexagon.tsx
index 5d94b05b45..90018e312b 100644
--- a/libs/components/board-shapes/src/hexagon-util/components/DrawHexagon.tsx
+++ b/libs/components/board-shapes/src/hexagon-util/components/DrawHexagon.tsx
@@ -1,6 +1,6 @@
+import type { ShapeStyles } from '@toeverything/components/board-types';
import * as React from 'react';
import { getShapeStyle } from '../../shared';
-import type { ShapeStyles } from '@toeverything/components/board-types';
import {
getHexagonIndicatorPathTDSnapshot,
getHexagonPath,
diff --git a/libs/components/board-shapes/src/hexagon-util/components/HexagonBindingIndicator.tsx b/libs/components/board-shapes/src/hexagon-util/components/HexagonBindingIndicator.tsx
index 20cc6c7914..9ea7746669 100644
--- a/libs/components/board-shapes/src/hexagon-util/components/HexagonBindingIndicator.tsx
+++ b/libs/components/board-shapes/src/hexagon-util/components/HexagonBindingIndicator.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
import { BINDING_DISTANCE } from '@toeverything/components/board-types';
import { getHexagonPoints } from '../hexagon-helpers';
diff --git a/libs/components/board-shapes/src/hexagon-util/hexagon-helpers.ts b/libs/components/board-shapes/src/hexagon-util/hexagon-helpers.ts
index ea8497a3d0..77a17b32d2 100644
--- a/libs/components/board-shapes/src/hexagon-util/hexagon-helpers.ts
+++ b/libs/components/board-shapes/src/hexagon-util/hexagon-helpers.ts
@@ -1,8 +1,8 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import getStroke, { getStrokePoints } from 'perfect-freehand';
import type { ShapeStyles } from '@toeverything/components/board-types';
-import { getShapeStyle, getOffsetPolygon } from '../shared';
+import getStroke, { getStrokePoints } from 'perfect-freehand';
+import { getOffsetPolygon, getShapeStyle } from '../shared';
function getPonits(w: number, h: number) {
return [
[w / 5, 0],
diff --git a/libs/components/board-shapes/src/image-util/image-util.tsx b/libs/components/board-shapes/src/image-util/image-util.tsx
index 95515fd23b..2becfdcc84 100644
--- a/libs/components/board-shapes/src/image-util/image-util.tsx
+++ b/libs/components/board-shapes/src/image-util/image-util.tsx
@@ -1,20 +1,20 @@
-import * as React from 'react';
-import { Utils, HTMLContainer } from '@tldraw/core';
+import { HTMLContainer, Utils } from '@tldraw/core';
import {
- TDShapeType,
- TDMeta,
+ GHOSTED_OPACITY,
ImageShape,
TDImageAsset,
- GHOSTED_OPACITY,
+ TDMeta,
+ TDShapeType,
} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
+import { styled } from '@toeverything/components/ui';
+import * as React from 'react';
import {
defaultStyle,
getBoundsRectangle,
transformRectangle,
transformSingleRectangle,
} from '../shared';
-import { styled } from '@toeverything/components/ui';
+import { TDShapeUtil } from '../TDShapeUtil';
type T = ImageShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/index.ts b/libs/components/board-shapes/src/index.ts
index 1c7fd3be39..3fc00bbbbd 100644
--- a/libs/components/board-shapes/src/index.ts
+++ b/libs/components/board-shapes/src/index.ts
@@ -1,20 +1,23 @@
import { TDShape, TDShapeType } from '@toeverything/components/board-types';
-import type { TDShapeUtil } from './TDShapeUtil';
-import { RectangleUtil } from './rectangle-util';
-import { TriangleUtil } from './triangle-util';
-import { HexagonUtil } from './hexagon-util';
import { ArrowUtil } from './arrow-util';
import { DrawUtil } from './draw-util';
-import { EllipseUtil } from './ellipse-util';
-import { GroupUtil } from './group-util';
-import { ImageUtil } from './image-util';
-import { VideoUtil } from './video-util';
import { EditorUtil } from './editor-util';
-import { PentagramUtil } from './pentagram-util';
-import { WhiteArrowUtil } from './white-arrow-util';
+import { EllipseUtil } from './ellipse-util';
import { FrameUtil } from './frame-util';
+import { GroupUtil } from './group-util';
+import { HexagonUtil } from './hexagon-util';
+import { ImageUtil } from './image-util';
+import { PentagramUtil } from './pentagram-util';
+import { RectangleUtil } from './rectangle-util';
+import type { TDShapeUtil } from './TDShapeUtil';
+import { TriangleUtil } from './triangle-util';
+import { VideoUtil } from './video-util';
+import { WhiteArrowUtil } from './white-arrow-util';
+export { clearPrevSize } from './shared/get-text-size';
+export { defaultStyle } from './shared/shape-styles';
export { TDShapeUtil } from './TDShapeUtil';
+export { getTrianglePoints } from './triangle-util/triangle-helpers';
export const Rectangle = new RectangleUtil();
export const Triangle = new TriangleUtil();
@@ -54,7 +57,3 @@ export const getShapeUtil = (
return shapeUtils[shape] as unknown as TDShapeUtil;
return shapeUtils[shape.type] as unknown as TDShapeUtil;
};
-
-export { getTrianglePoints } from './triangle-util/triangle-helpers';
-export { defaultStyle } from './shared/shape-styles';
-export { clearPrevSize } from './shared/get-text-size';
diff --git a/libs/components/board-shapes/src/pentagram-util/PentagramUtil.tsx b/libs/components/board-shapes/src/pentagram-util/PentagramUtil.tsx
index 74eb074c34..02770f4eea 100644
--- a/libs/components/board-shapes/src/pentagram-util/PentagramUtil.tsx
+++ b/libs/components/board-shapes/src/pentagram-util/PentagramUtil.tsx
@@ -1,36 +1,36 @@
-import * as React from 'react';
-import { Utils, SVGContainer, TLBounds } from '@tldraw/core';
-import {
- PentagramShape,
- TDShapeType,
- TDMeta,
- TDShape,
- DashStyle,
- BINDING_DISTANCE,
- GHOSTED_OPACITY,
- LABEL_POINT,
-} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
-import {
- defaultStyle,
- getBoundsRectangle,
- transformRectangle,
- transformSingleRectangle,
- getFontStyle,
- TextLabel,
- getShapeStyle,
-} from '../shared';
+import { SVGContainer, TLBounds, Utils } from '@tldraw/core';
import {
intersectBoundsPolygon,
intersectLineSegmentPolyline,
intersectRayLineSegment,
} from '@tldraw/intersect';
import Vec from '@tldraw/vec';
-import { getPentagramCentroid, getPentagramPoints } from './pentagram-helpers';
+import {
+ BINDING_DISTANCE,
+ DashStyle,
+ GHOSTED_OPACITY,
+ LABEL_POINT,
+ PentagramShape,
+ TDMeta,
+ TDShape,
+ TDShapeType,
+} from '@toeverything/components/board-types';
import { styled } from '@toeverything/components/ui';
-import { DrawPentagram } from './components/DrawPentagram';
+import * as React from 'react';
+import {
+ defaultStyle,
+ getBoundsRectangle,
+ getFontStyle,
+ getShapeStyle,
+ TextLabel,
+ transformRectangle,
+ transformSingleRectangle,
+} from '../shared';
+import { TDShapeUtil } from '../TDShapeUtil';
import { DashedPentagram } from './components/DashedPentagram';
+import { DrawPentagram } from './components/DrawPentagram';
import { PentagramBindingIndicator } from './components/PentagramBindingIndicator';
+import { getPentagramCentroid, getPentagramPoints } from './pentagram-helpers';
type T = PentagramShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/pentagram-util/components/DashedPentagram.tsx b/libs/components/board-shapes/src/pentagram-util/components/DashedPentagram.tsx
index 42c0189e49..5fc715e0c3 100644
--- a/libs/components/board-shapes/src/pentagram-util/components/DashedPentagram.tsx
+++ b/libs/components/board-shapes/src/pentagram-util/components/DashedPentagram.tsx
@@ -1,9 +1,9 @@
-import * as React from 'react';
import { Utils } from '@tldraw/core';
+import Vec from '@tldraw/vec';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import * as React from 'react';
import { getShapeStyle } from '../../shared';
import { getPentagramPoints } from '../pentagram-helpers';
-import Vec from '@tldraw/vec';
interface PentagramSvgProps {
id: string;
diff --git a/libs/components/board-shapes/src/pentagram-util/components/DrawPentagram.tsx b/libs/components/board-shapes/src/pentagram-util/components/DrawPentagram.tsx
index 9d2e1b99b9..17210e40aa 100644
--- a/libs/components/board-shapes/src/pentagram-util/components/DrawPentagram.tsx
+++ b/libs/components/board-shapes/src/pentagram-util/components/DrawPentagram.tsx
@@ -1,6 +1,6 @@
+import type { ShapeStyles } from '@toeverything/components/board-types';
import * as React from 'react';
import { getShapeStyle } from '../../shared';
-import type { ShapeStyles } from '@toeverything/components/board-types';
import {
getPentagramIndicatorPathTDSnapshot,
getPentagramPath,
diff --git a/libs/components/board-shapes/src/pentagram-util/components/PentagramBindingIndicator.tsx b/libs/components/board-shapes/src/pentagram-util/components/PentagramBindingIndicator.tsx
index 27981cbe38..61be5887ec 100644
--- a/libs/components/board-shapes/src/pentagram-util/components/PentagramBindingIndicator.tsx
+++ b/libs/components/board-shapes/src/pentagram-util/components/PentagramBindingIndicator.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
import { BINDING_DISTANCE } from '@toeverything/components/board-types';
import { getPentagramPoints } from '../pentagram-helpers';
diff --git a/libs/components/board-shapes/src/pentagram-util/pentagram-helpers.ts b/libs/components/board-shapes/src/pentagram-util/pentagram-helpers.ts
index addd55a5c6..155109bb1b 100644
--- a/libs/components/board-shapes/src/pentagram-util/pentagram-helpers.ts
+++ b/libs/components/board-shapes/src/pentagram-util/pentagram-helpers.ts
@@ -1,8 +1,8 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import getStroke, { getStrokePoints } from 'perfect-freehand';
import type { ShapeStyles } from '@toeverything/components/board-types';
-import { getShapeStyle, getOffsetPolygon } from '../shared';
+import getStroke, { getStrokePoints } from 'perfect-freehand';
+import { getOffsetPolygon, getShapeStyle } from '../shared';
function getPonits(w: number, h: number) {
return [
[0, (76 / 200) * h],
diff --git a/libs/components/board-shapes/src/rectangle-util/RectangleUtil.tsx b/libs/components/board-shapes/src/rectangle-util/RectangleUtil.tsx
index ec6cebb2f0..c5fbbaa4da 100644
--- a/libs/components/board-shapes/src/rectangle-util/RectangleUtil.tsx
+++ b/libs/components/board-shapes/src/rectangle-util/RectangleUtil.tsx
@@ -1,28 +1,28 @@
-import * as React from 'react';
-import { Utils, SVGContainer } from '@tldraw/core';
+import { SVGContainer, Utils } from '@tldraw/core';
import {
- RectangleShape,
DashStyle,
- TDShapeType,
- TDMeta,
GHOSTED_OPACITY,
LABEL_POINT,
+ RectangleShape,
+ TDMeta,
+ TDShapeType,
} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
+import { styled } from '@toeverything/components/ui';
+import * as React from 'react';
import {
defaultStyle,
- getShapeStyle,
getBoundsRectangle,
- transformRectangle,
getFontStyle,
+ getShapeStyle,
+ transformRectangle,
transformSingleRectangle,
} from '../shared';
import { TextLabel } from '../shared/text-label';
-import { getRectangleIndicatorPathTDSnapshot } from './rectangle-helpers';
-import { DrawRectangle } from './components/DrawRectangle';
-import { DashedRectangle } from './components/DashedRectangle';
+import { TDShapeUtil } from '../TDShapeUtil';
import { BindingIndicator } from './components/BindingIndicator';
-import { styled } from '@toeverything/components/ui';
+import { DashedRectangle } from './components/DashedRectangle';
+import { DrawRectangle } from './components/DrawRectangle';
+import { getRectangleIndicatorPathTDSnapshot } from './rectangle-helpers';
type T = RectangleShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/rectangle-util/components/BindingIndicator.tsx b/libs/components/board-shapes/src/rectangle-util/components/BindingIndicator.tsx
index 3fab0bfd74..ee349f1634 100644
--- a/libs/components/board-shapes/src/rectangle-util/components/BindingIndicator.tsx
+++ b/libs/components/board-shapes/src/rectangle-util/components/BindingIndicator.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
import { BINDING_DISTANCE } from '@toeverything/components/board-types';
interface BindingIndicatorProps {
diff --git a/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx b/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx
index 6b5289cac0..77ee2cec6a 100644
--- a/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx
+++ b/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx
@@ -1,7 +1,7 @@
-import * as React from 'react';
import { Utils } from '@tldraw/core';
-import { BINDING_DISTANCE } from '@toeverything/components/board-types';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import { BINDING_DISTANCE } from '@toeverything/components/board-types';
+import * as React from 'react';
import { getShapeStyle } from '../../shared';
interface RectangleSvgProps {
diff --git a/libs/components/board-shapes/src/rectangle-util/components/DrawRectangle.tsx b/libs/components/board-shapes/src/rectangle-util/components/DrawRectangle.tsx
index 291c7fea18..9858ac6983 100644
--- a/libs/components/board-shapes/src/rectangle-util/components/DrawRectangle.tsx
+++ b/libs/components/board-shapes/src/rectangle-util/components/DrawRectangle.tsx
@@ -1,6 +1,6 @@
+import type { ShapeStyles } from '@toeverything/components/board-types';
import * as React from 'react';
import { getShapeStyle } from '../../shared';
-import type { ShapeStyles } from '@toeverything/components/board-types';
import {
getRectangleIndicatorPathTDSnapshot,
getRectanglePath,
diff --git a/libs/components/board-shapes/src/rectangle-util/rectangle-helpers.ts b/libs/components/board-shapes/src/rectangle-util/rectangle-helpers.ts
index a815c6d550..4b10de4e38 100644
--- a/libs/components/board-shapes/src/rectangle-util/rectangle-helpers.ts
+++ b/libs/components/board-shapes/src/rectangle-util/rectangle-helpers.ts
@@ -1,7 +1,7 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import getStroke, { getStrokePoints } from 'perfect-freehand';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import getStroke, { getStrokePoints } from 'perfect-freehand';
import { getShapeStyle } from '../shared';
function getRectangleDrawPoints(
diff --git a/libs/components/board-shapes/src/shared/get-text-svg-element.ts b/libs/components/board-shapes/src/shared/get-text-svg-element.ts
index f6584e9a40..3f5a496ed7 100644
--- a/libs/components/board-shapes/src/shared/get-text-svg-element.ts
+++ b/libs/components/board-shapes/src/shared/get-text-svg-element.ts
@@ -1,11 +1,11 @@
import type { TLBounds } from '@tldraw/core';
-import { getFontFace, getFontSize } from './shape-styles';
-import { getTextAlign } from './get-text-align';
import {
- LINE_HEIGHT,
AlignStyle,
+ LINE_HEIGHT,
ShapeStyles,
} from '@toeverything/components/board-types';
+import { getTextAlign } from './get-text-align';
+import { getFontFace, getFontSize } from './shape-styles';
export function getTextSvgElement(
text: string,
diff --git a/libs/components/board-shapes/src/shared/index.ts b/libs/components/board-shapes/src/shared/index.ts
index b2a3abd316..95fe5ace99 100644
--- a/libs/components/board-shapes/src/shared/index.ts
+++ b/libs/components/board-shapes/src/shared/index.ts
@@ -1,12 +1,12 @@
+export * from './get-bounds-rectangle';
export * from './get-text-align';
export * from './get-text-size';
export * from './get-text-svg-element';
-export * from './shape-styles';
-export * from './get-bounds-rectangle';
-export * from './transform-rectangle';
-export * from './transform-single-rectangle';
-export * from './text-label';
-export * from './polygon-utils';
export * from './label-mask';
export * from './normalize-text';
+export * from './polygon-utils';
+export * from './shape-styles';
export * from './stop-propagation';
+export * from './text-label';
+export * from './transform-rectangle';
+export * from './transform-single-rectangle';
diff --git a/libs/components/board-shapes/src/shared/label-mask.tsx b/libs/components/board-shapes/src/shared/label-mask.tsx
index fe61b0e92f..d7b62eda1b 100644
--- a/libs/components/board-shapes/src/shared/label-mask.tsx
+++ b/libs/components/board-shapes/src/shared/label-mask.tsx
@@ -1,5 +1,4 @@
import type { TLBounds } from '@tldraw/core';
-import * as React from 'react';
interface WithLabelMaskProps {
id: string;
diff --git a/libs/components/board-shapes/src/shared/shape-styles.ts b/libs/components/board-shapes/src/shared/shape-styles.ts
index 9d0cc4fe29..b21ab6152a 100644
--- a/libs/components/board-shapes/src/shared/shape-styles.ts
+++ b/libs/components/board-shapes/src/shared/shape-styles.ts
@@ -1,13 +1,13 @@
import { Utils } from '@tldraw/core';
import {
- Theme,
+ AlignStyle,
ColorStyle,
DashStyle,
- ShapeStyles,
FontSizeStyle,
FontStyle,
- AlignStyle,
+ ShapeStyles,
StrokeWidth,
+ Theme,
} from '@toeverything/components/board-types';
const canvasLight = '#fafafa';
diff --git a/libs/components/board-shapes/src/shared/text-label.tsx b/libs/components/board-shapes/src/shared/text-label.tsx
index 02dc0056de..ba40f38f01 100644
--- a/libs/components/board-shapes/src/shared/text-label.tsx
+++ b/libs/components/board-shapes/src/shared/text-label.tsx
@@ -1,12 +1,12 @@
-import * as React from 'react';
-import { stopPropagation } from './stop-propagation';
import {
GHOSTED_OPACITY,
LETTER_SPACING,
} from '@toeverything/components/board-types';
-import { normalizeText } from './normalize-text';
import { styled } from '@toeverything/components/ui';
+import * as React from 'react';
import { getTextLabelSize } from './get-text-size';
+import { normalizeText } from './normalize-text';
+import { stopPropagation } from './stop-propagation';
import { TextAreaUtils } from './text-area-utils';
export interface TextLabelProps {
diff --git a/libs/components/board-shapes/src/triangle-util/TriangleUtil.tsx b/libs/components/board-shapes/src/triangle-util/TriangleUtil.tsx
index 7a5fc6963a..514287b1bd 100644
--- a/libs/components/board-shapes/src/triangle-util/TriangleUtil.tsx
+++ b/libs/components/board-shapes/src/triangle-util/TriangleUtil.tsx
@@ -1,36 +1,36 @@
-import * as React from 'react';
-import { Utils, SVGContainer, TLBounds } from '@tldraw/core';
-import {
- TriangleShape,
- TDShapeType,
- TDMeta,
- TDShape,
- DashStyle,
- BINDING_DISTANCE,
- GHOSTED_OPACITY,
- LABEL_POINT,
-} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
-import {
- defaultStyle,
- getBoundsRectangle,
- transformRectangle,
- transformSingleRectangle,
- getFontStyle,
- TextLabel,
- getShapeStyle,
-} from '../shared';
+import { SVGContainer, TLBounds, Utils } from '@tldraw/core';
import {
intersectBoundsPolygon,
intersectLineSegmentPolyline,
intersectRayLineSegment,
} from '@tldraw/intersect';
import Vec from '@tldraw/vec';
-import { getTriangleCentroid, getTrianglePoints } from './triangle-helpers';
+import {
+ BINDING_DISTANCE,
+ DashStyle,
+ GHOSTED_OPACITY,
+ LABEL_POINT,
+ TDMeta,
+ TDShape,
+ TDShapeType,
+ TriangleShape,
+} from '@toeverything/components/board-types';
import { styled } from '@toeverything/components/ui';
-import { DrawTriangle } from './components/DrawTriangle';
+import * as React from 'react';
+import {
+ defaultStyle,
+ getBoundsRectangle,
+ getFontStyle,
+ getShapeStyle,
+ TextLabel,
+ transformRectangle,
+ transformSingleRectangle,
+} from '../shared';
+import { TDShapeUtil } from '../TDShapeUtil';
import { DashedTriangle } from './components/DashedTriangle';
+import { DrawTriangle } from './components/DrawTriangle';
import { TriangleBindingIndicator } from './components/TriangleBindingIndicator';
+import { getTriangleCentroid, getTrianglePoints } from './triangle-helpers';
type T = TriangleShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/triangle-util/components/DashedTriangle.tsx b/libs/components/board-shapes/src/triangle-util/components/DashedTriangle.tsx
index 71b49b626b..b33914a43b 100644
--- a/libs/components/board-shapes/src/triangle-util/components/DashedTriangle.tsx
+++ b/libs/components/board-shapes/src/triangle-util/components/DashedTriangle.tsx
@@ -1,9 +1,9 @@
-import * as React from 'react';
import { Utils } from '@tldraw/core';
+import Vec from '@tldraw/vec';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import * as React from 'react';
import { getShapeStyle } from '../../shared';
import { getTrianglePoints } from '../triangle-helpers';
-import Vec from '@tldraw/vec';
interface TriangleSvgProps {
id: string;
diff --git a/libs/components/board-shapes/src/triangle-util/components/DrawTriangle.tsx b/libs/components/board-shapes/src/triangle-util/components/DrawTriangle.tsx
index b6a21cc449..4cbfdf8ce0 100644
--- a/libs/components/board-shapes/src/triangle-util/components/DrawTriangle.tsx
+++ b/libs/components/board-shapes/src/triangle-util/components/DrawTriangle.tsx
@@ -1,6 +1,6 @@
+import type { ShapeStyles } from '@toeverything/components/board-types';
import * as React from 'react';
import { getShapeStyle } from '../../shared';
-import type { ShapeStyles } from '@toeverything/components/board-types';
import {
getTriangleIndicatorPathTDSnapshot,
getTrianglePath,
diff --git a/libs/components/board-shapes/src/triangle-util/components/TriangleBindingIndicator.tsx b/libs/components/board-shapes/src/triangle-util/components/TriangleBindingIndicator.tsx
index 3953d705e9..078b534887 100644
--- a/libs/components/board-shapes/src/triangle-util/components/TriangleBindingIndicator.tsx
+++ b/libs/components/board-shapes/src/triangle-util/components/TriangleBindingIndicator.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
import { BINDING_DISTANCE } from '@toeverything/components/board-types';
import { getTrianglePoints } from '../triangle-helpers';
diff --git a/libs/components/board-shapes/src/triangle-util/triangle-helpers.ts b/libs/components/board-shapes/src/triangle-util/triangle-helpers.ts
index d1475364d4..892eb7eb1b 100644
--- a/libs/components/board-shapes/src/triangle-util/triangle-helpers.ts
+++ b/libs/components/board-shapes/src/triangle-util/triangle-helpers.ts
@@ -1,8 +1,8 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import getStroke, { getStrokePoints } from 'perfect-freehand';
import type { ShapeStyles } from '@toeverything/components/board-types';
-import { getShapeStyle, getOffsetPolygon } from '../shared';
+import getStroke, { getStrokePoints } from 'perfect-freehand';
+import { getOffsetPolygon, getShapeStyle } from '../shared';
export function getTrianglePoints(size: number[], offset = 0, rotation = 0) {
const [w, h] = size;
diff --git a/libs/components/board-shapes/src/video-util/video-util.tsx b/libs/components/board-shapes/src/video-util/video-util.tsx
index 1e00d830ad..22b51284d4 100644
--- a/libs/components/board-shapes/src/video-util/video-util.tsx
+++ b/libs/components/board-shapes/src/video-util/video-util.tsx
@@ -1,20 +1,20 @@
-import * as React from 'react';
-import { Utils, HTMLContainer } from '@tldraw/core';
+import { HTMLContainer, Utils } from '@tldraw/core';
import {
- TDShapeType,
- TDMeta,
- VideoShape,
- TDVideoAsset,
GHOSTED_OPACITY,
+ TDMeta,
+ TDShapeType,
+ TDVideoAsset,
+ VideoShape,
} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
+import { styled } from '@toeverything/components/ui';
+import * as React from 'react';
import {
defaultStyle,
getBoundsRectangle,
transformRectangle,
transformSingleRectangle,
} from '../shared';
-import { styled } from '@toeverything/components/ui';
+import { TDShapeUtil } from '../TDShapeUtil';
type T = VideoShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/white-arrow-util/WhiteArrowUtil.tsx b/libs/components/board-shapes/src/white-arrow-util/WhiteArrowUtil.tsx
index 877fe60f4b..b767dde966 100644
--- a/libs/components/board-shapes/src/white-arrow-util/WhiteArrowUtil.tsx
+++ b/libs/components/board-shapes/src/white-arrow-util/WhiteArrowUtil.tsx
@@ -1,39 +1,39 @@
-import * as React from 'react';
-import { Utils, SVGContainer, TLBounds } from '@tldraw/core';
-import {
- WhiteArrowShape,
- TDShapeType,
- TDMeta,
- TDShape,
- DashStyle,
- BINDING_DISTANCE,
- GHOSTED_OPACITY,
- LABEL_POINT,
-} from '@toeverything/components/board-types';
-import { TDShapeUtil } from '../TDShapeUtil';
-import {
- defaultStyle,
- getBoundsRectangle,
- transformRectangle,
- transformSingleRectangle,
- getFontStyle,
- TextLabel,
- getShapeStyle,
-} from '../shared';
+import { SVGContainer, TLBounds, Utils } from '@tldraw/core';
import {
intersectBoundsPolygon,
intersectLineSegmentPolyline,
intersectRayLineSegment,
} from '@tldraw/intersect';
import Vec from '@tldraw/vec';
+import {
+ BINDING_DISTANCE,
+ DashStyle,
+ GHOSTED_OPACITY,
+ LABEL_POINT,
+ TDMeta,
+ TDShape,
+ TDShapeType,
+ WhiteArrowShape,
+} from '@toeverything/components/board-types';
+import { styled } from '@toeverything/components/ui';
+import * as React from 'react';
+import {
+ defaultStyle,
+ getBoundsRectangle,
+ getFontStyle,
+ getShapeStyle,
+ TextLabel,
+ transformRectangle,
+ transformSingleRectangle,
+} from '../shared';
+import { TDShapeUtil } from '../TDShapeUtil';
+import { DashedWhiteArrow } from './components/DashedWhiteArrow';
+import { DrawWhiteArrow } from './components/DrawWhiteArrow';
+import { WhiteArrowBindingIndicator } from './components/WhiteArrowBindingIndicator';
import {
getWhiteArrowCentroid,
getWhiteArrowPoints,
} from './white-arrow-helpers';
-import { styled } from '@toeverything/components/ui';
-import { DrawWhiteArrow } from './components/DrawWhiteArrow';
-import { DashedWhiteArrow } from './components/DashedWhiteArrow';
-import { WhiteArrowBindingIndicator } from './components/WhiteArrowBindingIndicator';
type T = WhiteArrowShape;
type E = HTMLDivElement;
diff --git a/libs/components/board-shapes/src/white-arrow-util/components/DashedWhiteArrow.tsx b/libs/components/board-shapes/src/white-arrow-util/components/DashedWhiteArrow.tsx
index 7ad535e69c..16e3e12543 100644
--- a/libs/components/board-shapes/src/white-arrow-util/components/DashedWhiteArrow.tsx
+++ b/libs/components/board-shapes/src/white-arrow-util/components/DashedWhiteArrow.tsx
@@ -1,9 +1,9 @@
-import * as React from 'react';
import { Utils } from '@tldraw/core';
+import Vec from '@tldraw/vec';
import type { ShapeStyles } from '@toeverything/components/board-types';
+import * as React from 'react';
import { getShapeStyle } from '../../shared';
import { getWhiteArrowPoints } from '../white-arrow-helpers';
-import Vec from '@tldraw/vec';
interface WhiteArrowSvgProps {
id: string;
diff --git a/libs/components/board-shapes/src/white-arrow-util/components/DrawWhiteArrow.tsx b/libs/components/board-shapes/src/white-arrow-util/components/DrawWhiteArrow.tsx
index 352d756837..ff404c79d0 100644
--- a/libs/components/board-shapes/src/white-arrow-util/components/DrawWhiteArrow.tsx
+++ b/libs/components/board-shapes/src/white-arrow-util/components/DrawWhiteArrow.tsx
@@ -1,6 +1,6 @@
+import type { ShapeStyles } from '@toeverything/components/board-types';
import * as React from 'react';
import { getShapeStyle } from '../../shared';
-import type { ShapeStyles } from '@toeverything/components/board-types';
import {
getWhiteArrowIndicatorPathTDSnapshot,
getWhiteArrowPath,
diff --git a/libs/components/board-shapes/src/white-arrow-util/components/WhiteArrowBindingIndicator.tsx b/libs/components/board-shapes/src/white-arrow-util/components/WhiteArrowBindingIndicator.tsx
index e5196cf77b..d8bac6163c 100644
--- a/libs/components/board-shapes/src/white-arrow-util/components/WhiteArrowBindingIndicator.tsx
+++ b/libs/components/board-shapes/src/white-arrow-util/components/WhiteArrowBindingIndicator.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
import { BINDING_DISTANCE } from '@toeverything/components/board-types';
import { getWhiteArrowPoints } from '../white-arrow-helpers';
diff --git a/libs/components/board-shapes/src/white-arrow-util/white-arrow-helpers.ts b/libs/components/board-shapes/src/white-arrow-util/white-arrow-helpers.ts
index f05f5b42b2..587dbd251b 100644
--- a/libs/components/board-shapes/src/white-arrow-util/white-arrow-helpers.ts
+++ b/libs/components/board-shapes/src/white-arrow-util/white-arrow-helpers.ts
@@ -1,8 +1,8 @@
import { Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
-import getStroke, { getStrokePoints } from 'perfect-freehand';
import type { ShapeStyles } from '@toeverything/components/board-types';
-import { getShapeStyle, getOffsetPolygon } from '../shared';
+import getStroke, { getStrokePoints } from 'perfect-freehand';
+import { getOffsetPolygon, getShapeStyle } from '../shared';
function getPonits(w: number, h: number) {
return [
[w / 2, 0],
diff --git a/libs/components/board-state/src/data/filesystem.ts b/libs/components/board-state/src/data/filesystem.ts
index 79b6ba6c49..9825b1e591 100644
--- a/libs/components/board-state/src/data/filesystem.ts
+++ b/libs/components/board-state/src/data/filesystem.ts
@@ -1,11 +1,11 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import type { TDDocument, TDFile } from '@toeverything/components/board-types';
-import type { FileSystemHandle } from './browser-fs-access';
-import { get as getFromIdb, set as setToIdb } from 'idb-keyval';
import {
IMAGE_EXTENSIONS,
VIDEO_EXTENSIONS,
} from '@toeverything/components/board-types';
+import { get as getFromIdb, set as setToIdb } from 'idb-keyval';
+import type { FileSystemHandle } from './browser-fs-access';
const options = { mode: 'readwrite' as const };
diff --git a/libs/components/board-state/src/data/index.ts b/libs/components/board-state/src/data/index.ts
index 6d9a5d19e1..a00fd2a70b 100644
--- a/libs/components/board-state/src/data/index.ts
+++ b/libs/components/board-state/src/data/index.ts
@@ -1,3 +1,3 @@
-export * from './migrate';
-export * from './filesystem';
export * from './browser-fs-access';
+export * from './filesystem';
+export * from './migrate';
diff --git a/libs/components/board-state/src/data/migrate.spec.ts b/libs/components/board-state/src/data/migrate.spec.ts
index d26024f1b4..30e0612c5f 100644
--- a/libs/components/board-state/src/data/migrate.spec.ts
+++ b/libs/components/board-state/src/data/migrate.spec.ts
@@ -1,7 +1,7 @@
-import type { TDDocument } from '~types';
import { TldrawApp } from '~state';
import oldDoc from '~test/documents/old-doc';
import oldDoc2 from '~test/documents/old-doc-2';
+import type { TDDocument } from '~types';
describe('When migrating bindings', () => {
it('migrates a document without a version', () => {
diff --git a/libs/components/board-state/src/data/migrate.ts b/libs/components/board-state/src/data/migrate.ts
index 98eb1dd330..d4c14a5edf 100644
--- a/libs/components/board-state/src/data/migrate.ts
+++ b/libs/components/board-state/src/data/migrate.ts
@@ -1,10 +1,8 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import {
Decoration,
- FontStyle,
TDDocument,
TDShapeType,
- // TextShape
} from '@toeverything/components/board-types';
export function migrate(document: TDDocument, newVersion: number): TDDocument {
diff --git a/libs/components/board-state/src/idb-clipboard.ts b/libs/components/board-state/src/idb-clipboard.ts
index d7f47cc4a8..15af99f995 100644
--- a/libs/components/board-state/src/idb-clipboard.ts
+++ b/libs/components/board-state/src/idb-clipboard.ts
@@ -1,4 +1,4 @@
-import { get, set, del } from 'idb-keyval';
+import { del, get, set } from 'idb-keyval';
// Used for clipboard
diff --git a/libs/components/board-state/src/index.ts b/libs/components/board-state/src/index.ts
index 11dcb37c9f..e43f912111 100644
--- a/libs/components/board-state/src/index.ts
+++ b/libs/components/board-state/src/index.ts
@@ -1,5 +1,5 @@
+export { deepCopy } from './manager/deep-copy';
+export { TLDR } from './tldr';
export { TldrawApp } from './tldraw-app';
export type { TldrawAppCtorProps } from './tldraw-app';
-export { TLDR } from './tldr';
-export { deepCopy } from './manager/deep-copy';
export { BaseTool, Status as BaseToolStatus } from './types/tool';
diff --git a/libs/components/board-state/src/manager/state-manager.ts b/libs/components/board-state/src/manager/state-manager.ts
index ae3c757da6..908e9134ad 100644
--- a/libs/components/board-state/src/manager/state-manager.ts
+++ b/libs/components/board-state/src/manager/state-manager.ts
@@ -1,9 +1,9 @@
-import createVanilla, { StoreApi } from 'zustand/vanilla';
-import create, { UseBoundStore } from 'zustand';
-import * as idb from 'idb-keyval';
-import { deepCopy } from './deep-copy';
-import type { Patch, Command } from '@toeverything/components/board-types';
import { Utils } from '@tldraw/core';
+import type { Command, Patch } from '@toeverything/components/board-types';
+import * as idb from 'idb-keyval';
+import create, { UseBoundStore } from 'zustand';
+import createVanilla, { StoreApi } from 'zustand/vanilla';
+import { deepCopy } from './deep-copy';
export class StateManager> {
/**
diff --git a/libs/components/board-state/src/tldr.ts b/libs/components/board-state/src/tldr.ts
index a96f33317b..fbd3304121 100644
--- a/libs/components/board-state/src/tldr.ts
+++ b/libs/components/board-state/src/tldr.ts
@@ -1,31 +1,31 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
-import { TLBounds, TLTransformInfo, Utils, TLPageState } from '@tldraw/core';
+import { TLBounds, TLPageState, TLTransformInfo, Utils } from '@tldraw/core';
import {
- TDSnapshot,
- ShapesWithProp,
- TDShape,
- TDBinding,
- TDPage,
- TldrawCommand,
- TldrawPatch,
- TDShapeType,
- ArrowShape,
- TDHandle,
- TDExportType,
- BINDING_DISTANCE,
-} from '@toeverything/components/board-types';
+ intersectRayBounds,
+ intersectRayEllipse,
+ intersectRayLineSegment,
+} from '@tldraw/intersect';
import { Vec } from '@tldraw/vec';
import type { TDShapeUtil } from '@toeverything/components/board-shapes';
import {
getShapeUtil,
getTrianglePoints,
} from '@toeverything/components/board-shapes';
-import { deepCopy } from './manager/deep-copy';
import {
- intersectRayBounds,
- intersectRayEllipse,
- intersectRayLineSegment,
-} from '@tldraw/intersect';
+ ArrowShape,
+ BINDING_DISTANCE,
+ ShapesWithProp,
+ TDBinding,
+ TDExportType,
+ TDHandle,
+ TDPage,
+ TDShape,
+ TDShapeType,
+ TDSnapshot,
+ TldrawCommand,
+ TldrawPatch,
+} from '@toeverything/components/board-types';
+import { deepCopy } from './manager/deep-copy';
const isDev = process.env['NODE_ENV'] === 'development';
diff --git a/libs/components/board-state/src/tldraw-app.ts b/libs/components/board-state/src/tldraw-app.ts
index b062cc8b8c..34a392db72 100644
--- a/libs/components/board-state/src/tldraw-app.ts
+++ b/libs/components/board-state/src/tldraw-app.ts
@@ -3,77 +3,77 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable no-restricted-syntax */
-import { Vec } from '@tldraw/vec';
import {
+ TLBounds,
TLBoundsEventHandler,
TLBoundsHandleEventHandler,
- TLKeyboardEventHandler,
- TLShapeCloneHandler,
TLCanvasEventHandler,
+ TLDropEventHandler,
+ TLKeyboardEventHandler,
TLPageState,
TLPinchEventHandler,
TLPointerEventHandler,
+ TLShapeCloneHandler,
TLWheelEventHandler,
Utils,
- TLBounds,
- TLDropEventHandler,
} from '@tldraw/core';
+import { Vec } from '@tldraw/vec';
+import {
+ clearPrevSize,
+ defaultStyle,
+ shapeUtils,
+} from '@toeverything/components/board-shapes';
import {
- FlipType,
- TDDocument,
- MoveType,
AlignType,
- StretchType,
+ ArrowShape,
+ BaseSessionType,
DistributeType,
+ FIT_TO_SCREEN_PADDING,
+ FlipType,
+ GRID_SIZE,
+ GroupShape,
+ IMAGE_EXTENSIONS,
+ MoveType,
+ SessionType,
ShapeStyles,
+ StretchType,
+ SVG_EXPORT_PADDING,
+ TDAsset,
+ TDAssets,
+ TDAssetType,
+ TDBinding,
+ TDDocument,
+ TDExport,
+ TDExportType,
+ TDPage,
TDShape,
TDShapeType,
TDSnapshot,
TDStatus,
- TDPage,
- TDBinding,
- GroupShape,
- TldrawCommand,
- TDUser,
- SessionType,
TDToolType,
- TDAssetType,
- TDAsset,
- TDAssets,
- TDExport,
- ArrowShape,
- TDExportType,
+ TDUser,
+ TldrawCommand,
USER_COLORS,
- FIT_TO_SCREEN_PADDING,
- GRID_SIZE,
- IMAGE_EXTENSIONS,
VIDEO_EXTENSIONS,
- SVG_EXPORT_PADDING,
- BaseSessionType,
} from '@toeverything/components/board-types';
+import { MIN_PAGE_WIDTH } from '@toeverything/components/editor-core';
import {
- migrate,
FileSystemHandle,
- loadFileHandle,
- openFromFileSystem,
- saveToFileSystem,
- openAssetFromFileSystem,
fileToBase64,
fileToText,
getImageSizeFromSrc,
getVideoSizeFromSrc,
+ loadFileHandle,
+ migrate,
+ openAssetFromFileSystem,
+ openFromFileSystem,
+ saveToFileSystem,
} from './data';
-import { TLDR } from './tldr';
-import {
- shapeUtils,
- defaultStyle,
- clearPrevSize,
-} from '@toeverything/components/board-shapes';
-import { StateManager } from './manager/state-manager';
import { getClipboard, setClipboard } from './idb-clipboard';
+import { StateManager } from './manager/state-manager';
+import { TLDR } from './tldr';
import type { Commands } from './types/commands';
import type { BaseTool } from './types/tool';
-import { MIN_PAGE_WIDTH } from '@toeverything/components/editor-core';
const uuid = Utils.uniqueId();
@@ -171,6 +171,10 @@ interface TDCallbacks {
* (optional) A callback to run when the user exports their page or selection.
*/
onExport?: (app: TldrawApp, info: TDExport) => Promise;
+ /**
+ * (optional) A callback to run when the shape is copied.
+ */
+ onCopy?: (e: ClipboardEvent, ids: string[]) => void;
}
export interface TldrawAppCtorProps {
@@ -440,7 +444,6 @@ export class TldrawApp extends StateManager {
if (visitedShapes.has(fromShape)) {
return;
}
-
// We only need to update the binding's "from" shape (an arrow)
const fromDelta = TLDR.update_arrow_bindings(
page,
@@ -856,7 +859,6 @@ export class TldrawApp extends StateManager {
if (!page.bindings[binding.id]) {
return;
}
-
const fromShape = page.shapes[binding.fromId] as ArrowShape;
if (visitedShapes.has(fromShape)) {
@@ -864,6 +866,7 @@ export class TldrawApp extends StateManager {
}
// We only need to update the binding's "from" shape (an arrow)
+
const fromDelta = TLDR.update_arrow_bindings(page, fromShape);
visitedShapes.add(fromShape);
@@ -1898,12 +1901,14 @@ export class TldrawApp extends StateManager {
/**
* Copy one or more shapes to the clipboard.
* @param ids The ids of the shapes to copy.
+ * @param pageId
+ * @param e
*/
- copy = (
+ copy = async (
ids = this.selectedIds,
pageId = this.currentPageId,
e?: ClipboardEvent
- ): this => {
+ ) => {
e?.preventDefault();
this.clipboard = this.get_clipboard(ids, pageId);
@@ -1919,17 +1924,24 @@ export class TldrawApp extends StateManager {
if (e) {
e.clipboardData?.setData('text/html', tldrawString);
+ await this.callbacks.onCopy?.(e, this.selectedIds);
}
- if (navigator.clipboard && window.ClipboardItem) {
- navigator.clipboard.write([
- new ClipboardItem({
- 'text/html': new Blob([tldrawString], {
- type: 'text/html',
- }),
- }),
- ]);
- }
+ /**
+ * Reasons for not using Clipboard API for now:
+ * 1. The `clipboardData.setData` method temporarily satisfies the need for replication functionality
+ * 2. Clipboard API requires the user to agree to access(https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)
+ *
+ * **/
+ // if (navigator.clipboard && window.ClipboardItem) {
+ // navigator.clipboard.write([
+ // new ClipboardItem({
+ // 'text/html': new Blob([tldrawString], {
+ // type: 'text/html',
+ // }),
+ // }),
+ // ]);
+ // }
this.pasteInfo.offset = [0, 0];
this.pasteInfo.center = [0, 0];
@@ -3840,12 +3852,9 @@ export class TldrawApp extends StateManager {
};
private get_viewbox_from_svg = (svgStr: string | ArrayBuffer | null) => {
- const viewBoxRegex =
- /.*?viewBox=["'](-?[\d.]+[, ]+-?[\d.]+[, ][\d.]+[, ][\d.]+)["']/;
-
if (typeof svgStr === 'string') {
- const matches = svgStr.match(viewBoxRegex);
- return matches && matches.length >= 2 ? matches[1] : null;
+ const viewBox = new DOMParser().parseFromString(svgStr, 'text/xml');
+ return viewBox.children[0].getAttribute('viewBox');
}
console.warn('could not get viewbox from svg string');
@@ -3981,7 +3990,7 @@ export class TldrawApp extends StateManager {
this.patchState({
settings: {
forcePanning:
- this.currentTool.type === TDShapeType.HandDraw,
+ this.currentTool.type === TDShapeType.HandDrag,
},
});
this.spaceKey = false;
@@ -4128,7 +4137,7 @@ export class TldrawApp extends StateManager {
};
onPointerDown: TLPointerEventHandler = (info, e) => {
- if (e.buttons === 4) {
+ if (e.button === 1) {
this.patchState({
settings: {
forcePanning: true,
@@ -4145,6 +4154,13 @@ export class TldrawApp extends StateManager {
};
onPointerUp: TLPointerEventHandler = (info, e) => {
+ if (e.button === 1) {
+ this.patchState({
+ settings: {
+ forcePanning: false,
+ },
+ });
+ }
this.isPointing = false;
this.updateInputs(info, e);
this.currentTool.onPointerUp?.(info, e);
diff --git a/libs/components/board-state/src/types/commands.ts b/libs/components/board-state/src/types/commands.ts
index 5a26a22788..44e4b4025c 100644
--- a/libs/components/board-state/src/types/commands.ts
+++ b/libs/components/board-state/src/types/commands.ts
@@ -1,17 +1,17 @@
import type { TLBounds } from '@tldraw/core';
-import type { TldrawApp } from '../tldraw-app';
import type {
- TldrawCommand,
AlignType,
- TDShape,
- TDBinding,
DistributeType,
FlipType,
- MoveType,
- StretchType,
- ShapeStyles,
GroupShape,
+ MoveType,
+ ShapeStyles,
+ StretchType,
+ TDBinding,
+ TDShape,
+ TldrawCommand,
} from '@toeverything/components/board-types';
+import type { TldrawApp } from '../tldraw-app';
export interface Commands {
alignShapes(app: TldrawApp, ids: string[], type: AlignType): TldrawCommand;
diff --git a/libs/components/board-state/src/types/tool.ts b/libs/components/board-state/src/types/tool.ts
index d318a8b679..931d8bc63c 100644
--- a/libs/components/board-state/src/types/tool.ts
+++ b/libs/components/board-state/src/types/tool.ts
@@ -4,11 +4,11 @@ import {
TLPointerEventHandler,
Utils,
} from '@tldraw/core';
-import type { TldrawApp } from '../tldraw-app';
import {
TDEventHandler,
TDToolType,
} from '@toeverything/components/board-types';
+import type { TldrawApp } from '../tldraw-app';
export enum Status {
Idle = 'idle',
diff --git a/libs/components/board-tools/src/arrow-tool/arrow-tool.ts b/libs/components/board-tools/src/arrow-tool/arrow-tool.ts
index 8ad9f4255f..49be807408 100644
--- a/libs/components/board-tools/src/arrow-tool/arrow-tool.ts
+++ b/libs/components/board-tools/src/arrow-tool/arrow-tool.ts
@@ -1,9 +1,8 @@
-import { Utils, TLPointerEventHandler } from '@tldraw/core';
+import { TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Arrow } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
-import { services } from '@toeverything/datasource/db-service';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class ArrowTool extends BaseTool {
override type = TDShapeType.Arrow as const;
diff --git a/libs/components/board-tools/src/draw-tool/draw-tool.ts b/libs/components/board-tools/src/draw-tool/draw-tool.ts
index a82eabfe4c..ad1a73ad87 100644
--- a/libs/components/board-tools/src/draw-tool/draw-tool.ts
+++ b/libs/components/board-tools/src/draw-tool/draw-tool.ts
@@ -1,7 +1,7 @@
-import { Utils, TLPointerEventHandler } from '@tldraw/core';
+import { TLPointerEventHandler, Utils } from '@tldraw/core';
import { Draw } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
enum Status {
Idle = 'idle',
diff --git a/libs/components/board-tools/src/editor-tool/editor-tool.ts b/libs/components/board-tools/src/editor-tool/editor-tool.ts
index f0da22a0c1..ae12af6c59 100644
--- a/libs/components/board-tools/src/editor-tool/editor-tool.ts
+++ b/libs/components/board-tools/src/editor-tool/editor-tool.ts
@@ -2,8 +2,8 @@
import { TLPointerEventHandler } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Editor } from '@toeverything/components/board-shapes';
-import { TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { TDShapeType } from '@toeverything/components/board-types';
import { services } from '@toeverything/datasource/db-service';
export class EditorTool extends BaseTool {
diff --git a/libs/components/board-tools/src/ellipse-tool/ellipse-tool.ts b/libs/components/board-tools/src/ellipse-tool/ellipse-tool.ts
index d0b8edfdbc..dff670ac3c 100644
--- a/libs/components/board-tools/src/ellipse-tool/ellipse-tool.ts
+++ b/libs/components/board-tools/src/ellipse-tool/ellipse-tool.ts
@@ -1,8 +1,8 @@
-import { Utils, TLPointerEventHandler, TLBoundsCorner } from '@tldraw/core';
+import { TLBoundsCorner, TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Ellipse } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class EllipseTool extends BaseTool {
override type = TDShapeType.Ellipse as const;
diff --git a/libs/components/board-tools/src/erase-tool/erase-tool.ts b/libs/components/board-tools/src/erase-tool/erase-tool.ts
index a5b68aea00..64be36aac1 100644
--- a/libs/components/board-tools/src/erase-tool/erase-tool.ts
+++ b/libs/components/board-tools/src/erase-tool/erase-tool.ts
@@ -1,7 +1,7 @@
-import Vec from '@tldraw/vec';
import type { TLPointerEventHandler } from '@tldraw/core';
-import { SessionType, DEAD_ZONE } from '@toeverything/components/board-types';
+import Vec from '@tldraw/vec';
import { BaseTool } from '@toeverything/components/board-state';
+import { DEAD_ZONE, SessionType } from '@toeverything/components/board-types';
enum Status {
Idle = 'idle',
diff --git a/libs/components/board-tools/src/frame-tool/frame-tool.ts b/libs/components/board-tools/src/frame-tool/frame-tool.ts
index 7e9b34ec36..8f50e45d46 100644
--- a/libs/components/board-tools/src/frame-tool/frame-tool.ts
+++ b/libs/components/board-tools/src/frame-tool/frame-tool.ts
@@ -1,13 +1,8 @@
-import {
- Utils,
- TLPointerEventHandler,
- TLBoundsCorner,
- TLBoundsHandleEventHandler,
-} from '@tldraw/core';
+import { TLBoundsCorner, TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Frame } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class FrameTool extends BaseTool {
override type = TDShapeType.Frame as const;
diff --git a/libs/components/board-tools/src/hand-draw/hand-draw-tool.ts b/libs/components/board-tools/src/hand-drag/hand-drag-tool.ts
similarity index 79%
rename from libs/components/board-tools/src/hand-draw/hand-draw-tool.ts
rename to libs/components/board-tools/src/hand-drag/hand-drag-tool.ts
index 180b936442..3730447935 100644
--- a/libs/components/board-tools/src/hand-draw/hand-draw-tool.ts
+++ b/libs/components/board-tools/src/hand-drag/hand-drag-tool.ts
@@ -1,9 +1,7 @@
-import { TLPointerEventHandler } from '@tldraw/core';
// import { Draw } from '@toeverything/components/board-shapes';
-import { Vec } from '@tldraw/vec';
-import { TDShapeType } from '@toeverything/components/board-types';
import { BaseTool } from '@toeverything/components/board-state';
+import { TDShapeType } from '@toeverything/components/board-types';
enum Status {
Idle = 'idle',
@@ -11,8 +9,8 @@ enum Status {
Draw = 'draw',
}
-export class HandDrawTool extends BaseTool {
- override type = TDShapeType.HandDraw as const;
+export class HandDragTool extends BaseTool {
+ override type = TDShapeType.HandDrag as const;
override status: Status = Status.Idle;
diff --git a/libs/components/board-tools/src/hand-drag/index.ts b/libs/components/board-tools/src/hand-drag/index.ts
new file mode 100644
index 0000000000..5c11fb0d69
--- /dev/null
+++ b/libs/components/board-tools/src/hand-drag/index.ts
@@ -0,0 +1 @@
+export * from './hand-drag-tool';
diff --git a/libs/components/board-tools/src/hand-draw/index.ts b/libs/components/board-tools/src/hand-draw/index.ts
deleted file mode 100644
index cc6c154d06..0000000000
--- a/libs/components/board-tools/src/hand-draw/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './hand-draw-tool';
diff --git a/libs/components/board-tools/src/hexagon-tool/hexagon-tool.ts b/libs/components/board-tools/src/hexagon-tool/hexagon-tool.ts
index 60b2269a4a..cc4a1a6ab7 100644
--- a/libs/components/board-tools/src/hexagon-tool/hexagon-tool.ts
+++ b/libs/components/board-tools/src/hexagon-tool/hexagon-tool.ts
@@ -1,8 +1,8 @@
-import { Utils, TLPointerEventHandler, TLBoundsCorner } from '@tldraw/core';
+import { TLBoundsCorner, TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Hexagon } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class HexagonTool extends BaseTool {
override type = TDShapeType.Triangle as const;
diff --git a/libs/components/board-tools/src/highlight-tool/highlight-tool.ts b/libs/components/board-tools/src/highlight-tool/highlight-tool.ts
index 9e7096d2e2..dd4aa270a8 100644
--- a/libs/components/board-tools/src/highlight-tool/highlight-tool.ts
+++ b/libs/components/board-tools/src/highlight-tool/highlight-tool.ts
@@ -1,12 +1,12 @@
-import { Utils, TLPointerEventHandler } from '@tldraw/core';
+import { TLPointerEventHandler, Utils } from '@tldraw/core';
import { Draw } from '@toeverything/components/board-shapes';
-import {
- SessionType,
- TDShapeType,
- DashStyle,
- StrokeWidth,
-} from '@toeverything/components/board-types';
import { BaseTool } from '@toeverything/components/board-state';
+import {
+ DashStyle,
+ SessionType,
+ StrokeWidth,
+ TDShapeType,
+} from '@toeverything/components/board-types';
enum Status {
Idle = 'idle',
diff --git a/libs/components/board-tools/src/index.ts b/libs/components/board-tools/src/index.ts
index 1bc068a078..f55558c94c 100644
--- a/libs/components/board-tools/src/index.ts
+++ b/libs/components/board-tools/src/index.ts
@@ -1,21 +1,21 @@
import { TDShapeType, TDToolType } from '@toeverything/components/board-types';
import { ArrowTool } from './arrow-tool';
-import { LineTool } from './line-tool';
import { DrawTool } from './draw-tool';
-import { PencilTool } from './pencil-tool';
-import { HighlightTool } from './highlight-tool';
-import { EllipseTool } from './ellipse-tool';
-import { RectangleTool } from './rectangle-tool';
-import { TriangleTool } from './triangle-tool';
-import { SelectTool } from './select-tool';
-import { EraseTool } from './erase-tool';
import { EditorTool } from './editor-tool';
-import { HexagonTool } from './hexagon-tool';
-import { PentagramTool } from './pentagram-tool';
-import { WhiteArrowTool } from './white-arrow-tool';
-import { LaserTool } from './laser-tool';
-import { HandDrawTool } from './hand-draw';
+import { EllipseTool } from './ellipse-tool';
+import { EraseTool } from './erase-tool';
import { FrameTool } from './frame-tool/frame-tool';
+import { HandDragTool } from './hand-drag';
+import { HexagonTool } from './hexagon-tool';
+import { HighlightTool } from './highlight-tool';
+import { LaserTool } from './laser-tool';
+import { LineTool } from './line-tool';
+import { PencilTool } from './pencil-tool';
+import { PentagramTool } from './pentagram-tool';
+import { RectangleTool } from './rectangle-tool';
+import { SelectTool } from './select-tool';
+import { TriangleTool } from './triangle-tool';
+import { WhiteArrowTool } from './white-arrow-tool';
export interface ToolsMap {
select: typeof SelectTool;
@@ -32,7 +32,7 @@ export interface ToolsMap {
[TDShapeType.Highlight]: typeof HighlightTool;
[TDShapeType.Editor]: typeof EditorTool;
[TDShapeType.WhiteArrow]: typeof WhiteArrowTool;
- [TDShapeType.HandDraw]: typeof HandDrawTool;
+ [TDShapeType.HandDrag]: typeof HandDragTool;
[TDShapeType.Laser]: typeof LaserTool;
[TDShapeType.Frame]: typeof FrameTool;
}
@@ -59,6 +59,6 @@ export const tools: { [K in TDToolType]: ToolsMap[K] } = {
[TDShapeType.Hexagon]: HexagonTool,
[TDShapeType.WhiteArrow]: WhiteArrowTool,
[TDShapeType.Laser]: LaserTool,
- [TDShapeType.HandDraw]: HandDrawTool,
+ [TDShapeType.HandDrag]: HandDragTool,
[TDShapeType.Frame]: FrameTool,
};
diff --git a/libs/components/board-tools/src/laser-tool/laser-tool.ts b/libs/components/board-tools/src/laser-tool/laser-tool.ts
index 2f0d754112..2c48f3aaea 100644
--- a/libs/components/board-tools/src/laser-tool/laser-tool.ts
+++ b/libs/components/board-tools/src/laser-tool/laser-tool.ts
@@ -2,8 +2,8 @@ import { TLPointerEventHandler } from '@tldraw/core';
// import { Draw } from '@toeverything/components/board-shapes';
import { Vec } from '@tldraw/vec';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
enum Status {
Idle = 'idle',
diff --git a/libs/components/board-tools/src/line-tool/line-tool.ts b/libs/components/board-tools/src/line-tool/line-tool.ts
index 48e27cc5f6..9d552e746f 100644
--- a/libs/components/board-tools/src/line-tool/line-tool.ts
+++ b/libs/components/board-tools/src/line-tool/line-tool.ts
@@ -1,8 +1,8 @@
-import { Utils, TLPointerEventHandler } from '@tldraw/core';
+import { TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Arrow } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class LineTool extends BaseTool {
override type = TDShapeType.Line as const;
diff --git a/libs/components/board-tools/src/pencil-tool/pencil-tool.ts b/libs/components/board-tools/src/pencil-tool/pencil-tool.ts
index d174dab6f9..ebfdef462c 100644
--- a/libs/components/board-tools/src/pencil-tool/pencil-tool.ts
+++ b/libs/components/board-tools/src/pencil-tool/pencil-tool.ts
@@ -1,11 +1,11 @@
-import { Utils, TLPointerEventHandler } from '@tldraw/core';
+import { TLPointerEventHandler, Utils } from '@tldraw/core';
import { Draw } from '@toeverything/components/board-shapes';
+import { BaseTool } from '@toeverything/components/board-state';
import {
DashStyle,
SessionType,
TDShapeType,
} from '@toeverything/components/board-types';
-import { BaseTool } from '@toeverything/components/board-state';
enum Status {
Idle = 'idle',
diff --git a/libs/components/board-tools/src/pentagram-tool/pentagram-tool.ts b/libs/components/board-tools/src/pentagram-tool/pentagram-tool.ts
index 98c8fd474a..395e561704 100644
--- a/libs/components/board-tools/src/pentagram-tool/pentagram-tool.ts
+++ b/libs/components/board-tools/src/pentagram-tool/pentagram-tool.ts
@@ -1,8 +1,8 @@
-import { Utils, TLPointerEventHandler, TLBoundsCorner } from '@tldraw/core';
+import { TLBoundsCorner, TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Pentagram } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class PentagramTool extends BaseTool {
override type = TDShapeType.Pentagram as const;
diff --git a/libs/components/board-tools/src/rectangle-tool/rectangle-tool.ts b/libs/components/board-tools/src/rectangle-tool/rectangle-tool.ts
index 2bbd3dec2d..4d9db886c7 100644
--- a/libs/components/board-tools/src/rectangle-tool/rectangle-tool.ts
+++ b/libs/components/board-tools/src/rectangle-tool/rectangle-tool.ts
@@ -1,8 +1,8 @@
-import { Utils, TLPointerEventHandler, TLBoundsCorner } from '@tldraw/core';
+import { TLBoundsCorner, TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Rectangle } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class RectangleTool extends BaseTool {
override type = TDShapeType.Rectangle as const;
diff --git a/libs/components/board-tools/src/select-tool/select-tool.ts b/libs/components/board-tools/src/select-tool/select-tool.ts
index 3c96d0fa56..44028e1077 100644
--- a/libs/components/board-tools/src/select-tool/select-tool.ts
+++ b/libs/components/board-tools/src/select-tool/select-tool.ts
@@ -4,19 +4,18 @@ import {
TLBoundsEventHandler,
TLBoundsHandleEventHandler,
TLCanvasEventHandler,
- TLPointerEventHandler,
TLKeyboardEventHandler,
+ TLPointerEventHandler,
TLShapeCloneHandler,
Utils,
} from '@tldraw/core';
+import Vec from '@tldraw/vec';
+import { BaseTool, TLDR } from '@toeverything/components/board-state';
import {
- SessionType,
- TDShapeType,
CLONING_DISTANCE,
DEAD_ZONE,
+ SessionType,
} from '@toeverything/components/board-types';
-import { BaseTool, TLDR } from '@toeverything/components/board-state';
-import Vec from '@tldraw/vec';
enum Status {
Idle = 'idle',
diff --git a/libs/components/board-tools/src/triangle-tool/triangle-tool.ts b/libs/components/board-tools/src/triangle-tool/triangle-tool.ts
index 519124fd0c..901c593c7e 100644
--- a/libs/components/board-tools/src/triangle-tool/triangle-tool.ts
+++ b/libs/components/board-tools/src/triangle-tool/triangle-tool.ts
@@ -1,8 +1,8 @@
-import { Utils, TLPointerEventHandler, TLBoundsCorner } from '@tldraw/core';
+import { TLBoundsCorner, TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { Triangle } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class TriangleTool extends BaseTool {
override type = TDShapeType.Triangle as const;
diff --git a/libs/components/board-tools/src/white-arrow-tool/white-arrow-tool.ts b/libs/components/board-tools/src/white-arrow-tool/white-arrow-tool.ts
index b658367609..52f266d1bd 100644
--- a/libs/components/board-tools/src/white-arrow-tool/white-arrow-tool.ts
+++ b/libs/components/board-tools/src/white-arrow-tool/white-arrow-tool.ts
@@ -1,8 +1,8 @@
-import { Utils, TLPointerEventHandler, TLBoundsCorner } from '@tldraw/core';
+import { TLBoundsCorner, TLPointerEventHandler, Utils } from '@tldraw/core';
import Vec from '@tldraw/vec';
import { WhiteArrow } from '@toeverything/components/board-shapes';
-import { SessionType, TDShapeType } from '@toeverything/components/board-types';
import { BaseTool, BaseToolStatus } from '@toeverything/components/board-state';
+import { SessionType, TDShapeType } from '@toeverything/components/board-types';
export class WhiteArrowTool extends BaseTool {
override type = TDShapeType.Triangle as const;
diff --git a/libs/components/board-types/src/index.ts b/libs/components/board-types/src/index.ts
index ffe2c74601..be20e4cb42 100644
--- a/libs/components/board-types/src/index.ts
+++ b/libs/components/board-types/src/index.ts
@@ -1,3 +1,3 @@
-export * from './types';
export * from './constants';
export * from './session';
+export * from './types';
diff --git a/libs/components/board-types/src/session.ts b/libs/components/board-types/src/session.ts
index 1ae279f987..5954eef165 100644
--- a/libs/components/board-types/src/session.ts
+++ b/libs/components/board-types/src/session.ts
@@ -1,5 +1,5 @@
import { TLPerformanceMode } from '@tldraw/core';
-import { TDSnapshot, Patch } from './types';
+import { Patch, TDSnapshot } from './types';
export enum SessionType {
Transform = 'transform',
diff --git a/libs/components/board-types/src/types.ts b/libs/components/board-types/src/types.ts
index 6f80a965bc..78d0cfca8a 100644
--- a/libs/components/board-types/src/types.ts
+++ b/libs/components/board-types/src/types.ts
@@ -1,24 +1,24 @@
/* eslint-disable max-lines */
import type {
- TLPage,
- TLUser,
- TLPageState,
+ TLAsset,
TLBinding,
TLBoundsCorner,
TLBoundsEdge,
- TLShape,
- TLHandle,
- TLSnapLine,
- TLPinchEventHandler,
- TLKeyboardEventHandler,
- TLPointerEventHandler,
- TLWheelEventHandler,
- TLCanvasEventHandler,
TLBoundsEventHandler,
TLBoundsHandleEventHandler,
+ TLCanvasEventHandler,
+ TLHandle,
+ TLKeyboardEventHandler,
+ TLPage,
+ TLPageState,
+ TLPinchEventHandler,
+ TLPointerEventHandler,
+ TLShape,
TLShapeBlurHandler,
TLShapeCloneHandler,
- TLAsset,
+ TLSnapLine,
+ TLUser,
+ TLWheelEventHandler,
} from '@tldraw/core';
/* -------------------------------------------------- */
@@ -212,7 +212,7 @@ export type TDToolType =
| TDShapeType.WhiteArrow
| TDShapeType.Editor
| TDShapeType.Frame
- | TDShapeType.HandDraw;
+ | TDShapeType.HandDrag;
export type Easing =
| 'linear'
@@ -287,7 +287,7 @@ export enum TDShapeType {
Video = 'video',
Editor = 'editor',
WhiteArrow = 'white-arrow',
- HandDraw = 'hand-draw',
+ HandDrag = 'hand-drag',
Frame = 'frame',
}
diff --git a/libs/components/common/src/lib/index.ts b/libs/components/common/src/lib/index.ts
index 9a1eea5191..f42927223e 100644
--- a/libs/components/common/src/lib/index.ts
+++ b/libs/components/common/src/lib/index.ts
@@ -1,5 +1,6 @@
import { BaseEditor } from 'slate';
import { ReactEditor } from 'slate-react';
+import { DoubleLinkElement } from './text/plugins/DoubleLink';
import { LinkElement } from './text/plugins/link';
import { RefLinkElement } from './text/plugins/reflink';
@@ -8,7 +9,8 @@ export type CustomElement =
| { type: string; children: CustomElement[] }
| CustomText
| LinkElement
- | RefLinkElement;
+ | RefLinkElement
+ | DoubleLinkElement;
declare module 'slate' {
interface CustomTypes {
Editor: BaseEditor & ReactEditor;
@@ -19,35 +21,32 @@ declare module 'slate' {
export { BlockPreview, StyledBlockPreview } from './block-preview';
export { default as Button } from './button';
-export type { CommonListItem } from './list';
-export { CommonList, BackLink, commonListContainer } from './list';
-export * from './Logo';
-export { default as Toolbar } from './toolbar';
export { CollapsibleTitle } from './collapsible-title';
-
-export * from './text';
-
+export * from './comming-soon/CommingSoon';
export {
- NewpageIcon,
+ AddIcon,
ClockIcon,
- ViewSidebarIcon,
+ CloseIcon,
+ CodeBlockInlineIcon,
+ DocumentIcon,
+ FilterIcon,
+ FullScreenIcon,
+ HighlighterDuotoneIcon,
+ KanbanIcon,
ListIcon,
- SpaceIcon,
+ NewpageIcon,
+ PagesIcon,
PencilDotDuotoneIcon,
PencilDuotoneIcon,
- HighlighterDuotoneIcon,
- CodeBlockInlineIcon,
- PagesIcon,
- CloseIcon,
- DocumentIcon,
- TodoListIcon,
- KanbanIcon,
- TableIcon,
- AddIcon,
- FilterIcon,
SorterIcon,
- FullScreenIcon,
+ SpaceIcon,
+ TableIcon,
+ TodoListIcon,
UnGroupIcon,
+ ViewSidebarIcon,
} from './icon';
-
-export * from './comming-soon/CommingSoon';
+export { BackLink, CommonList, commonListContainer } from './list';
+export type { CommonListItem } from './list';
+export * from './Logo';
+export * from './text';
+export { default as Toolbar } from './toolbar';
diff --git a/libs/components/common/src/lib/list/index.tsx b/libs/components/common/src/lib/list/index.tsx
index 8f57a1d871..c00a4e1415 100644
--- a/libs/components/common/src/lib/list/index.tsx
+++ b/libs/components/common/src/lib/list/index.tsx
@@ -1,8 +1,4 @@
-import { useState } from 'react';
-import { useNavigate } from 'react-router';
-import clsx from 'clsx';
-import style9 from 'style9';
-
+import { BackwardUndoIcon } from '@toeverything/components/icons';
import {
BaseButton,
ListButton,
@@ -12,9 +8,11 @@ import {
} from '@toeverything/components/ui';
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import { BlockSearchItem } from '@toeverything/datasource/jwt';
-
+import clsx from 'clsx';
+import { useState } from 'react';
+import { useNavigate } from 'react-router';
+import style9 from 'style9';
import { BlockPreview } from '../block-preview';
-import { BackwardUndoIcon } from '@toeverything/components/icons';
export const commonListContainer = 'commonListContainer';
@@ -28,6 +26,7 @@ export type CommonListItem = {
divider?: string;
content?: Content;
block?: BlockSearchItem;
+ renderCustom?: (props: CommonListItem) => JSX.Element;
};
type MenuItemsProps = {
@@ -45,7 +44,7 @@ export const CommonList = (props: MenuItemsProps) => {
// ]);
// TODO Insert bidirectional link to be developed
const JSONUnsupportedBlockTypes = ['page'];
- let usedItems = items.filter(item => {
+ const usedItems = items.filter(item => {
return !JSONUnsupportedBlockTypes.includes(item?.content?.id);
});
return (
@@ -58,7 +57,9 @@ export const CommonList = (props: MenuItemsProps) => {
>
{usedItems?.length ? (
usedItems.map((item, idx) => {
- if (item.block) {
+ if (item.renderCustom) {
+ return item.renderCustom(item);
+ } else if (item.block) {
return (
{
switch (element.type) {
case 'link': {
+ if (element.linkType === 'doubleLink') {
+ return ;
+ }
return (
{
}
}
+ if (leaf.doubleLinkSearch) {
+ customChildren = (
+
+ {customChildren}
+
+ );
+ }
+
customChildren = (
{customChildren}
diff --git a/libs/components/common/src/lib/text/plugins/DoubleLink.tsx b/libs/components/common/src/lib/text/plugins/DoubleLink.tsx
new file mode 100644
index 0000000000..e4bcb9bec2
--- /dev/null
+++ b/libs/components/common/src/lib/text/plugins/DoubleLink.tsx
@@ -0,0 +1,40 @@
+import { PagesIcon } from '@toeverything/components/icons';
+import React, { useCallback } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { Descendant } from 'slate';
+import { RenderElementProps } from 'slate-react';
+
+export type DoubleLinkElement = {
+ type: 'link';
+ workspaceId: string;
+ blockId: string;
+ children: Descendant[];
+ id: string;
+};
+
+export const DoubleLinkComponent = (props: RenderElementProps) => {
+ const { attributes, children, element } = props;
+ const doubleLinkElement = element as DoubleLinkElement;
+ const navigate = useNavigate();
+
+ const handleClickLinkText = useCallback(
+ (event: React.MouseEvent) => {
+ const { workspaceId, blockId } = doubleLinkElement;
+ navigate(`/${workspaceId}/${blockId}`);
+ },
+ [doubleLinkElement, navigate]
+ );
+
+ return (
+
+
+
+ {children}
+
+
+ );
+};
diff --git a/libs/components/common/src/lib/text/slate-utils.ts b/libs/components/common/src/lib/text/slate-utils.ts
index 1783d79cab..fd1de5f674 100644
--- a/libs/components/common/src/lib/text/slate-utils.ts
+++ b/libs/components/common/src/lib/text/slate-utils.ts
@@ -2,28 +2,29 @@
import {
Descendant,
Editor,
+ Location,
+ Node as SlateNode,
+ Path,
Point,
- Transforms,
Range,
Text,
- Location,
- Path,
- Node as SlateNode,
+ Transforms,
} from 'slate';
import { ReactEditor } from 'slate-react';
-
-import {
- getCommentsIdsOnTextNode,
- getEditorMarkForCommentId,
- MARKDOWN_STYLE_MAP,
- MatchRes,
-} from './utils';
+import type { CustomElement } from '..';
import {
fontBgColorPalette,
fontColorPalette,
type TextAlignOptions,
type TextStyleMark,
} from './constants';
+import {
+ getCommentsIdsOnTextNode,
+ getEditorMarkForCommentId,
+ getRandomString,
+ MARKDOWN_STYLE_MAP,
+ MatchRes,
+} from './utils';
function isInlineAndVoid(editor: Editor, el: any) {
return editor.isInline(el) && editor.isVoid(el);
@@ -246,7 +247,11 @@ Editor.insertText = function (
const { path, offset } = at;
if (text.length > 0) {
const marks = Editor.marks(editor);
- if (text === '\u0020' && Object.keys(marks).length) {
+ if (
+ text === '\u0020' &&
+ Object.keys(marks).length &&
+ !(marks as any).doubleLinkSearch
+ ) {
// If the input is a space and the mark has content, remove the mark
const newPath = [path[0], path[1] + 1];
const newPoint = {
@@ -567,8 +572,56 @@ class SlateUtils {
anchor: point1,
focus: point2,
});
- // @ts-ignore
- return fragment[0].children;
+ if (!fragment.length) {
+ console.error('Debug information:', point1, point2, fragment);
+ throw new Error('Failed to get content between!');
+ }
+
+ if (fragment.length > 1) {
+ console.warn(
+ 'Fragment length is greater than one, ' +
+ 'please be careful if there is missing content!\n' +
+ 'Debug information:',
+ point1,
+ point2,
+ fragment
+ );
+ }
+
+ const firstFragment = fragment[0];
+ if (!('type' in firstFragment)) {
+ console.error('Debug information:', point1, point2, fragment);
+ throw new Error(
+ 'Failed to get content between! type of firstFragment not found!'
+ );
+ }
+
+ const fragmentChildren = firstFragment.children;
+
+ const textChildren: CustomElement[] = [];
+ for (let i = 0; i < fragmentChildren.length; i++) {
+ const child = fragmentChildren[i];
+ if ('type' in child && child.type === 'link') {
+ i !== fragmentChildren.length - 1 && textChildren.push(child);
+ continue;
+ }
+ if (!('text' in child)) {
+ console.error('Debug information:', point1, point2, fragment);
+ throw new Error('Fragment exists nested!');
+ }
+ // Filter empty string
+ if (child.text === '') {
+ continue;
+ }
+ textChildren.push(child);
+ }
+ // If nothing, should preserve empty string
+ // Fix Slate Cannot get the start point in the node at path [0] because it has no start text node.
+ if (!textChildren.length) {
+ textChildren.push({ text: '' });
+ }
+
+ return textChildren;
}
public getSplitContentsBySelection() {
@@ -1041,34 +1094,130 @@ class SlateUtils {
});
}
- public insertReference(reference: string) {
- try {
- // Transforms.setSelection(this.editor, this.getEndSelection());
- const { anchor, focus } = this.getEndSelection();
- Transforms.insertNodes(
+ public setDoubleLinkSearchSlash(point: Point) {
+ const str = Editor.string(this.editor, {
+ anchor: this.getStart(),
+ focus: point,
+ });
+ if (str.endsWith('[[')) {
+ Transforms.select(this.editor, {
+ anchor: point,
+ focus: Object.assign({}, point, {
+ offset: point.offset - 2,
+ }),
+ });
+ Editor.addMark(this.editor, 'doubleLinkSearch', true);
+ Transforms.select(this.editor, {
+ anchor: this.editor.selection.anchor,
+ focus: this.editor.selection.anchor,
+ });
+ }
+ }
+
+ public getDoubleLinkSearchSlashText() {
+ const nodes = Editor.nodes(this.editor, {
+ at: [],
+ //@ts-ignore
+ match: node => !!node.doubleLinkSearch,
+ });
+ const searchNode = nodes.next().value;
+ if (searchNode && (searchNode[0] as { text?: string }).text) {
+ return (searchNode[0] as { text?: string }).text;
+ }
+ return '';
+ }
+
+ public setSelectDoubleLinkSearchSlash() {
+ const nodes = Editor.nodes(this.editor, {
+ at: [],
+ //@ts-ignore
+ match: node => !!node.doubleLinkSearch,
+ });
+ const searchNode = nodes.next().value;
+ if (searchNode) {
+ const text = (searchNode[0] as { text?: string })?.text || '';
+ const path = searchNode[1];
+ const anchor = Editor.before(
this.editor,
{
- type: 'reflink',
- reference,
- children: [],
+ path,
+ offset: 1,
},
- { at: focus || anchor }
+ {
+ unit: 'offset',
+ }
);
-
- // requestAnimationFrame(() => {
- // console.log(this.editor.selection, this.editor.insertNode);
- // this.editor.insertNode({
- // type: 'reflink',
- // reference,
- // children: [{ text: '' }]
- // });
- // // Transforms.select();
- // });
- } catch (e) {
- console.log(e);
+ const focus = Editor.after(
+ this.editor,
+ {
+ path,
+ offset: text.length - 1,
+ },
+ {
+ unit: 'offset',
+ }
+ );
+ Transforms.select(this.editor, { anchor, focus });
}
}
+ public removeDoubleLinkSearchSlash(isRemoveSlash?: boolean) {
+ if (isRemoveSlash) {
+ const nodes = Editor.nodes(this.editor, {
+ at: [],
+ //@ts-ignore
+ match: node => !!node.doubleLinkSearch,
+ });
+ const searchNode = nodes.next().value;
+ if (searchNode) {
+ const text = (searchNode[0] as { text?: string })?.text || '';
+ if (text.startsWith('[[')) {
+ const path = searchNode[1];
+ Transforms.delete(this.editor, {
+ at: {
+ path,
+ offset: 0,
+ },
+ distance: text.length,
+ unit: 'character',
+ });
+ }
+ }
+ }
+ Transforms.setNodes(
+ this.editor,
+ { doubleLinkSearch: null } as Partial,
+ {
+ at: [],
+ match: node => {
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ //@ts-ignore
+ return !!node.doubleLinkSearch;
+ },
+ }
+ );
+ this.editor.removeMark('doubleLinkSearch');
+ }
+
+ public insertDoubleLink(
+ workspaceId: string,
+ linkBlockId: string,
+ children: any[]
+ ) {
+ const link = {
+ type: 'link',
+ linkType: 'doubleLink',
+ workspaceId: workspaceId,
+ blockId: linkBlockId,
+ children: children,
+ id: getRandomString('link'),
+ };
+ Transforms.insertNodes(this.editor, link);
+ requestAnimationFrame(() => {
+ ReactEditor.focus(this.editor);
+ });
+ }
+
/** todo improve if selection is collapsed */
public getCommentsIdsBySelection() {
const commentedTextNodes = Editor.nodes(this.editor, {
diff --git a/libs/components/editor-blocks/src/blocks/bullet/BulletView.tsx b/libs/components/editor-blocks/src/blocks/bullet/BulletView.tsx
index 5a15a78554..9f77eda6cb 100644
--- a/libs/components/editor-blocks/src/blocks/bullet/BulletView.tsx
+++ b/libs/components/editor-blocks/src/blocks/bullet/BulletView.tsx
@@ -173,7 +173,7 @@ export const BulletView = ({ block, editor }: CreateView) => {
}
return true;
} else {
- return tabBlock(block, isShiftKey);
+ return tabBlock(editor, block, isShiftKey);
}
};
diff --git a/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx b/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx
index 86881478ff..86b43908d1 100644
--- a/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx
+++ b/libs/components/editor-blocks/src/blocks/embed-link/EmbedLinkView.tsx
@@ -1,12 +1,12 @@
-import { useState } from 'react';
-import { CreateView } from '@toeverything/framework/virgo';
import {
BlockPendantProvider,
useOnSelect,
} from '@toeverything/components/editor-core';
-import { Upload } from '../../components/upload/upload';
+import { CreateView } from '@toeverything/framework/virgo';
+import { useState } from 'react';
import { SourceView } from '../../components/source-view';
import { LinkContainer } from '../../components/style-container';
+import { Upload } from '../../components/upload/upload';
const MESSAGES = {
ADD_EMBED_LINK: 'Add embed link',
@@ -38,7 +38,6 @@ export const EmbedLinkView = (props: EmbedLinkView) => {
{embedLinkUrl ? (
{
- {editor.isWhiteboard ? null : (
+ {editor.isEdgeless ? null : (
)}
diff --git a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
index 76220d7ff0..837772bed2 100644
--- a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
@@ -1,11 +1,18 @@
-import type { KanbanCard } from '@toeverything/components/editor-core';
import {
+ KanbanCard,
RenderBlock,
+ useEditor,
useKanban,
- useRefPage,
} from '@toeverything/components/editor-core';
-import { styled } from '@toeverything/components/ui';
+import { PenIcon } from '@toeverything/components/icons';
+import {
+ IconButton,
+ MuiClickAwayListener,
+ styled,
+} from '@toeverything/components/ui';
import { useFlag } from '@toeverything/datasource/feature-flags';
+import { useState, type MouseEvent } from 'react';
+import { useRefPage } from './RefPage';
const CardContent = styled('div')({
margin: '20px',
@@ -23,6 +30,7 @@ const CardActions = styled('div')({
fontWeight: '300',
color: '#98ACBD',
transition: 'all ease-in 0.2s',
+ zIndex: 1,
':hover': {
background: '#F5F7F8',
@@ -39,11 +47,13 @@ const PlusIcon = styled('div')({
});
const CardContainer = styled('div')({
+ position: 'relative',
display: 'flex',
flexDirection: 'column',
backgroundColor: '#fff',
border: '1px solid #E2E7ED',
borderRadius: '5px',
+ overflow: 'hidden',
[CardActions.toString()]: {
opacity: '0',
@@ -55,6 +65,23 @@ const CardContainer = styled('div')({
},
});
+const Overlay = styled('div')({
+ position: 'absolute',
+ width: '100%',
+ height: '100%',
+ background: 'transparent',
+
+ '& > *': {
+ visibility: 'hidden',
+ position: 'absolute',
+ right: '24px',
+ top: '16px',
+ },
+ '&:hover > *': {
+ visibility: 'visible',
+ },
+});
+
export const CardItem = ({
id,
block,
@@ -64,24 +91,43 @@ export const CardItem = ({
}) => {
const { addSubItem } = useKanban();
const { openSubPage } = useRefPage();
+ const [editable, setEditable] = useState(false);
const showKanbanRefPageFlag = useFlag('ShowKanbanRefPage', false);
+ const { editor } = useEditor();
+
const onAddItem = async () => {
+ setEditable(true);
await addSubItem(block);
};
const onClickCard = async () => {
- showKanbanRefPageFlag && openSubPage(id);
+ openSubPage(id);
+ };
+
+ const onClickPen = (e: MouseEvent) => {
+ e.stopPropagation();
+ setEditable(true);
+ editor.selectionManager.activeNodeByNodeId(block.id);
};
return (
-
-
-
-
-
-
- Add a sub-block
-
-
+ setEditable(false)}>
+
+
+
+
+ {showKanbanRefPageFlag && !editable && (
+
+
+
+
+
+ )}
+
+
+ Add a sub-block
+
+
+
);
};
diff --git a/libs/components/editor-core/src/ref-page/ModalPage.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/RefPage.tsx
similarity index 80%
rename from libs/components/editor-core/src/ref-page/ModalPage.tsx
rename to libs/components/editor-blocks/src/blocks/group/scene-kanban/RefPage.tsx
index 52e1d6554f..3d223d121d 100644
--- a/libs/components/editor-core/src/ref-page/ModalPage.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/RefPage.tsx
@@ -1,7 +1,7 @@
+import { useEditor } from '@toeverything/components/editor-core';
import { MuiBackdrop, styled, useTheme } from '@toeverything/components/ui';
import { createContext, ReactNode, useContext, useState } from 'react';
import { createPortal } from 'react-dom';
-import { RenderBlock } from '../render-block';
const Dialog = styled('div')({
flex: 1,
@@ -30,7 +30,7 @@ const Modal = ({ open, children }: { open: boolean; children?: ReactNode }) => {
onClick={closeSubPage}
>
{
+ onClick={(e: { stopPropagation: () => void }) => {
e.stopPropagation();
}}
>
@@ -43,9 +43,21 @@ const Modal = ({ open, children }: { open: boolean; children?: ReactNode }) => {
};
const ModalPage = ({ blockId }: { blockId: string | null }) => {
+ const { editor, editorElement } = useEditor();
+
+ const AffineEditor = editorElement as any;
+
return (
- {blockId && }
+ {blockId && (
+
+ )}
);
};
diff --git a/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx
index 27d5543177..73424708a7 100644
--- a/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/SceneKanban.tsx
@@ -4,30 +4,33 @@ import { SceneKanbanContext } from './context';
import { CardContainerWrapper } from './dndable/wrapper/CardContainerWrapper';
import type { ComponentType } from 'react';
import type { CreateView } from '@toeverything/framework/virgo';
+import { RefPageProvider } from './RefPage';
export const SceneKanban: ComponentType = withKanban(
({ editor, block }) => {
const { kanban } = useKanban();
return (
-
- (
-
- )}
- />
-
+
+
+ (
+
+ )}
+ />
+
+
);
}
);
diff --git a/libs/components/editor-blocks/src/blocks/group/utils/weak-sql/weakSqlCreator.ts b/libs/components/editor-blocks/src/blocks/group/utils/weak-sql/weakSqlCreator.ts
index 47debf2175..6d980155fa 100644
--- a/libs/components/editor-blocks/src/blocks/group/utils/weak-sql/weakSqlCreator.ts
+++ b/libs/components/editor-blocks/src/blocks/group/utils/weak-sql/weakSqlCreator.ts
@@ -49,7 +49,7 @@ const weakSqlCreator = (weak_sql_express = ''): Promise => {
constraints.push({
field: field.trim(),
relation: relation.trim() as Relation,
- value: pickValue(value.replace(/&&|&|;/, '').trim()),
+ value: pickValue(value.replace(/&&|&|;/g, '').trim()),
});
/* meaningless return value */
diff --git a/libs/components/editor-blocks/src/blocks/image/ImageView.tsx b/libs/components/editor-blocks/src/blocks/image/ImageView.tsx
index 692b63e17e..886c10fc97 100644
--- a/libs/components/editor-blocks/src/blocks/image/ImageView.tsx
+++ b/libs/components/editor-blocks/src/blocks/image/ImageView.tsx
@@ -1,7 +1,7 @@
import {
+ BlockPendantProvider,
useCurrentView,
useOnSelect,
- BlockPendantProvider,
} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
import { services } from '@toeverything/datasource/db-service';
@@ -41,6 +41,18 @@ const ImageBlock = styled('div')({
},
'.progress': {},
});
+const ImageShade = styled('div')(({ theme }) => {
+ return {
+ position: 'absolute',
+ top: 0,
+ bottom: 0,
+ left: 0,
+ zIndex: 2,
+ right: 0,
+ background: 'transparent',
+ };
+});
+
const KanbanImageContainer = styled('div')<{ isSelected: boolean }>(
({ theme, isSelected }) => {
return {
@@ -56,73 +68,72 @@ const KanbanImageContainer = styled('div')<{ isSelected: boolean }>(
);
export const ImageView = ({ block, editor }: ImageView) => {
const workspace = editor.workspace;
- const [imgUrl, set_image_url] = useState();
+ const [imgUrl, setImageUrl] = useState();
const [imgWidth, setImgWidth] = useState(0);
- const [ratio, set_ratio] = useState(0);
- const resize_box = useRef(null);
+ const [ratio, setRatio] = useState(0);
+ const resizeBox = useRef(null);
const [currentView] = useCurrentView();
const [isSelect, setIsSelect] = useState();
useOnSelect(block.id, (isSelect: boolean) => {
setIsSelect(isSelect);
});
- const img_load = (url: string) => {
- const boxWidth = resize_box.current.offsetWidth;
+ const imgLoad = (url: string) => {
+ const boxWidth = resizeBox.current.offsetWidth;
const imageStyle = block.getProperty('image_style');
if (imageStyle?.width) {
- set_ratio(imageStyle.width / imageStyle.height);
+ setRatio(imageStyle.width / imageStyle.height);
setImgWidth(imageStyle.width);
- set_image_url(url);
+ setImageUrl(url);
return;
}
const img = new Image();
img.src = url;
// load complete execution
img.onload = async () => {
- const img_radio = img.width / img.height;
+ const imgRadio = img.width / img.height;
if (img.width >= boxWidth - 20) {
img.width = boxWidth - 20;
}
- img.height = img.width / img_radio;
+ img.height = img.width / imgRadio;
block.setProperty('image_style', {
width: img.width,
height: img.height,
});
setImgWidth(img.width);
- set_image_url(url);
- set_ratio(img_radio);
+ setImageUrl(url);
+ setRatio(imgRadio);
};
img.onerror = e => {
console.log(e);
};
};
useEffect(() => {
- const style = window.getComputedStyle(block?.dom);
- const image_info = block.getProperty('image');
- const image_block_id = image_info?.value;
- const image_info_url = image_info?.url;
+ const imageInfo = block.getProperty('image');
+ const imageBlockId = imageInfo?.value;
+ const imageInfoUrl = imageInfo?.url;
- if (image_info_url) {
- img_load(image_info_url);
+ if (imageInfoUrl) {
+ imgLoad(imageInfoUrl);
return;
}
- if (image_block_id) {
- services.api.file.get(image_block_id, workspace).then(file_info => {
- img_load(file_info.url);
+ if (imageBlockId) {
+ services.api.file.get(imageBlockId, workspace).then(fileInfo => {
+ imgLoad(fileInfo.url);
});
}
}, [workspace]);
- const down_ref = useRef(null);
- const on_file_change = async (file: File) => {
+ const downRef = useRef(null);
+ const onFileChange = async (file: File) => {
const result = await services.api.file.create({
workspace: editor.workspace,
file: file,
});
- img_load(result.url);
+ imgLoad(result.url);
block.setProperty('image', {
value: result.id,
name: file.name,
@@ -130,11 +141,11 @@ export const ImageView = ({ block, editor }: ImageView) => {
type: file.type,
});
};
- const delete_file = () => {
+ const deleteFile = () => {
block.remove();
};
- const sava_link = (link: string) => {
- img_load(link);
+ const savaLink = (link: string) => {
+ imgLoad(link);
block.setProperty('image', {
value: '',
url: link,
@@ -143,27 +154,25 @@ export const ImageView = ({ block, editor }: ImageView) => {
type: 'link',
});
};
- const handle_click = async (e: React.MouseEvent) => {
- //TODO clear active selection
- // document.getElementsByTagName('body')[0].click();
- e.stopPropagation();
- e.nativeEvent.stopPropagation();
+ const handleClick = async (e: React.MouseEvent) => {
await editor.selectionManager.setSelectedNodesIds([block.id]);
await editor.selectionManager.activeNodeByNodeId(block.id, 'end');
};
const down_file = () => {
- if (down_ref) {
- down_ref.current.click();
+ if (downRef) {
+ downRef.current.click();
}
};
return (
-
+
+ {!isSelect ? (
+
+ ) : null}
{imgUrl ? (
{
// e.nativeEvent.stopPropagation();
e.stopPropagation();
@@ -175,7 +184,7 @@ export const ImageView = ({ block, editor }: ImageView) => {
viewStyle={{
width: imgWidth,
maxWidth:
- resize_box.current.offsetWidth - 20,
+ resizeBox.current.offsetWidth - 20,
minWidth: 32,
ratio: ratio,
}}
@@ -193,9 +202,9 @@ export const ImageView = ({ block, editor }: ImageView) => {
{
}}
>
diff --git a/libs/components/editor-blocks/src/blocks/numbered/NumberedView.tsx b/libs/components/editor-blocks/src/blocks/numbered/NumberedView.tsx
index ec0d690c96..38dac6fc75 100644
--- a/libs/components/editor-blocks/src/blocks/numbered/NumberedView.tsx
+++ b/libs/components/editor-blocks/src/blocks/numbered/NumberedView.tsx
@@ -167,7 +167,7 @@ export const NumberedView = ({ block, editor }: CreateView) => {
}
return true;
} else {
- tabBlock(block, isShiftKey);
+ tabBlock(editor, block, isShiftKey);
return false;
}
};
diff --git a/libs/components/editor-blocks/src/blocks/text/TextView.tsx b/libs/components/editor-blocks/src/blocks/text/TextView.tsx
index 2a9d77d577..5edf231217 100644
--- a/libs/components/editor-blocks/src/blocks/text/TextView.tsx
+++ b/libs/components/editor-blocks/src/blocks/text/TextView.tsx
@@ -2,13 +2,11 @@ import { useState } from 'react';
import { CustomText, TextProps } from '@toeverything/components/common';
import {
- mergeGroup,
+ BlockPendantProvider,
RenderBlockChildren,
splitGroup,
supportChildren,
- unwrapGroup,
useOnSelect,
- BlockPendantProvider,
} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
import { Protocol } from '@toeverything/datasource/db-service';
@@ -16,7 +14,7 @@ import { CreateView } from '@toeverything/framework/virgo';
import { BlockContainer } from '../../components/BlockContainer';
import { IndentWrapper } from '../../components/IndentWrapper';
import { TextManage } from '../../components/text-manage';
-import { tabBlock } from '../../utils/indent';
+import { dedentBlock, tabBlock } from '../../utils/indent';
interface CreateTextView extends CreateView {
// TODO: need to optimize
containerClassName?: string;
@@ -69,24 +67,36 @@ export const TextView = ({
const { contentBeforeSelection, contentAfterSelection } = splitContents;
const before = [...contentBeforeSelection.content];
const after = [...contentAfterSelection.content];
- const _nextBlockChildren = await block.children();
- const _nextBlock = await editor.createBlock('text');
- await _nextBlock.setProperty('text', {
+ const nextBlockChildren = await block.children();
+ const nextBlock = await editor.createBlock('text');
+ if (!nextBlock) {
+ throw new Error('Failed to create text block');
+ }
+ await nextBlock.setProperty('text', {
value: after as CustomText[],
});
- _nextBlock.append(..._nextBlockChildren);
- block.removeChildren();
await block.setProperty('text', {
value: before as CustomText[],
});
- await block.after(_nextBlock);
- editor.selectionManager.activeNodeByNodeId(_nextBlock.id);
+ if (editor.getRootBlockId() === block.id) {
+ // If the block is the root block,
+ // new block can not append as next sibling,
+ // all new blocks should be append as children.
+ await block.insert(0, [nextBlock]);
+ editor.selectionManager.activeNodeByNodeId(nextBlock.id);
+ return true;
+ }
+ await nextBlock.append(...nextBlockChildren);
+ await block.removeChildren();
+ await block.after(nextBlock);
+
+ editor.selectionManager.activeNodeByNodeId(nextBlock.id);
return true;
};
- const onBackspace: TextProps['handleBackSpace'] = async props => {
- return await editor.withSuspend(async () => {
+ const onBackspace: TextProps['handleBackSpace'] = editor.withBatch(
+ async props => {
const { isCollAndStart } = props;
if (!isCollAndStart) {
return false;
@@ -95,28 +105,44 @@ export const TextView = ({
await block.setType('text');
return true;
}
+ if (editor.getRootBlockId() === block.id) {
+ // Can not delete
+ return false;
+ }
const parentBlock = await block.parent();
if (!parentBlock) {
return false;
}
- const preParent = await parentBlock.previousSibling();
- if (Protocol.Block.Type.group === parentBlock.type) {
+
+ // The parent block is group block or is the root block.
+ // Merge block to previous sibling.
+ //
+ // - group/root <- parent block
+ // - text1 <- preNode
+ // - text2 <- press backspace before target block
+ // - children
+ //
+ // ---
+ //
+ // - group/root
+ // - text1text2 <- merge block to previous sibling
+ // - children <- children should switch parent block
+ if (
+ Protocol.Block.Type.group === parentBlock.type ||
+ editor.getRootBlockId() === parentBlock.id
+ ) {
const children = await block.children();
const preNode = await block.physicallyPerviousSibling();
// FIXME support children do not means has textBlock
// TODO: abstract this part of code
if (preNode) {
if (supportChildren(preNode)) {
- editor.suspend(true);
await editor.selectionManager.activePreviousNode(
block.id,
'end'
);
- if (
- block.getProperty('text').value[0] &&
- block.getProperty('text').value[0]?.text !== ''
- ) {
+ if (!block.blockProvider?.isEmpty()) {
const value = [
...preNode.getProperty('text').value,
...block.getProperty('text').value,
@@ -127,14 +153,14 @@ export const TextView = ({
}
await preNode.append(...children);
await block.remove();
- editor.suspend(false);
} else {
+ // If not pre node, block should be merged to the parent block
// TODO: point does not clear
await editor.selectionManager.activePreviousNode(
block.id,
'start'
);
- if (block.blockProvider.isEmpty()) {
+ if (block.blockProvider?.isEmpty()) {
await block.remove();
const parentChild = await parentBlock.children();
if (
@@ -142,6 +168,8 @@ export const TextView = ({
Protocol.Block.Type.group &&
!parentChild.length
) {
+ const preParent =
+ await parentBlock.previousSibling();
await editor.selectionManager.setSelectedNodesIds(
[preParent?.id ?? editor.getRootBlockId()]
);
@@ -182,20 +210,13 @@ export const TextView = ({
await parentBlock.remove();
}
return true;
- } else {
- const nextNodes = await block.nextSiblings();
- for (const nextNode of nextNodes) {
- await nextNode.remove();
- }
- block.append(...nextNodes);
- editor.commands.blockCommands.moveBlockAfter(
- block.id,
- parentBlock.id
- );
}
+
+ dedentBlock(editor, block);
return true;
- });
- };
+ }
+ );
+
const handleConvert = async (
toType: string,
options?: Record
@@ -211,7 +232,7 @@ export const TextView = ({
block.firstCreateFlag = true;
};
const onTab: TextProps['handleTab'] = async ({ isShiftKey }) => {
- await tabBlock(block, isShiftKey);
+ await tabBlock(editor, block, isShiftKey);
return true;
};
diff --git a/libs/components/editor-blocks/src/blocks/todo/TodoView.tsx b/libs/components/editor-blocks/src/blocks/todo/TodoView.tsx
index 961aa92735..8982f4695e 100644
--- a/libs/components/editor-blocks/src/blocks/todo/TodoView.tsx
+++ b/libs/components/editor-blocks/src/blocks/todo/TodoView.tsx
@@ -100,7 +100,7 @@ export const TodoView = ({ block, editor }: CreateView) => {
};
const on_tab: TextProps['handleTab'] = async ({ isShiftKey }) => {
- await tabBlock(block, isShiftKey);
+ await tabBlock(editor, block, isShiftKey);
return true;
};
diff --git a/libs/components/editor-blocks/src/blocks/youtube/index.ts b/libs/components/editor-blocks/src/blocks/youtube/index.ts
index 363e7d78a9..42f22bcda4 100644
--- a/libs/components/editor-blocks/src/blocks/youtube/index.ts
+++ b/libs/components/editor-blocks/src/blocks/youtube/index.ts
@@ -1,9 +1,9 @@
+import { Protocol } from '@toeverything/datasource/db-service';
import {
AsyncBlock,
BaseView,
SelectBlock,
} from '@toeverything/framework/virgo';
-import { Protocol } from '@toeverything/datasource/db-service';
import { YoutubeView } from './YoutubeView';
export class YoutubeBlock extends BaseView {
@@ -19,7 +19,10 @@ export class YoutubeBlock extends BaseView {
const tag_name = el.tagName;
if (tag_name === 'A' && el.parentElement?.childElementCount === 1) {
const href = el.getAttribute('href');
- if (href.indexOf('.youtube.com') !== -1) {
+ const allowedHosts = ['www.youtu.be', 'www.youtube.com'];
+ const host = new URL(href).host;
+
+ if (allowedHosts.includes(host)) {
return [
{
type: this.type,
diff --git a/libs/components/editor-blocks/src/components/source-view/BlockView.tsx b/libs/components/editor-blocks/src/components/source-view/BlockView.tsx
index 33c0f5d66c..0b2c953312 100644
--- a/libs/components/editor-blocks/src/components/source-view/BlockView.tsx
+++ b/libs/components/editor-blocks/src/components/source-view/BlockView.tsx
@@ -1,9 +1,9 @@
-import { memo, useEffect, useRef, useState } from 'react';
import { nanoid } from 'nanoid';
+import { memo, useEffect, useRef, useState } from 'react';
import { StyledBlockPreview } from '@toeverything/components/common';
+import { AsyncBlock, useEditor } from '@toeverything/components/editor-core';
import { services } from '@toeverything/datasource/db-service';
-import { AsyncBlock } from '@toeverything/framework/virgo';
import { debounce, sleep } from '@toeverything/utils';
const updateTitle = async (
@@ -73,15 +73,15 @@ const useBlockTitle = (block: AsyncBlock, blockId: string) => {
type BlockPreviewProps = {
block: AsyncBlock;
blockId: string;
- editorElement?: () => JSX.Element;
};
const InternalBlockPreview = (props: BlockPreviewProps) => {
const container = useRef();
const [preview, setPreview] = useState(true);
const title = useBlockTitle(props.block, props.blockId);
+ const { editorElement } = useEditor();
- const AffineEditor = props.editorElement as any;
+ const AffineEditor = editorElement as any;
useEffect(() => {
if (container?.current) {
diff --git a/libs/components/editor-blocks/src/components/source-view/SourceView.tsx b/libs/components/editor-blocks/src/components/source-view/SourceView.tsx
index b03189d7d4..27d19433bf 100644
--- a/libs/components/editor-blocks/src/components/source-view/SourceView.tsx
+++ b/libs/components/editor-blocks/src/components/source-view/SourceView.tsx
@@ -1,17 +1,15 @@
import {
AsyncBlock,
useCurrentView,
- useLazyIframe,
} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
-import { ReactElement, ReactNode, useEffect, useRef, useState } from 'react';
+import { ReactNode, useEffect, useRef, useState } from 'react';
import { SCENE_CONFIG } from '../../blocks/group/config';
import { BlockPreview } from './BlockView';
import { formatUrl } from './format-url';
export interface Props {
block: AsyncBlock;
- editorElement?: () => JSX.Element;
viewType?: string;
link: string;
// onResizeEnd: (data: any) => void;
@@ -150,7 +148,7 @@ const LoadingContiner = () => {
};
export const SourceView = (props: Props) => {
- const { link, isSelected, block, editorElement } = props;
+ const { link, isSelected, block } = props;
const src = formatUrl(link);
// let iframeShow = useLazyIframe(src, 3000, iframeContainer);
const [currentView] = useCurrentView();
@@ -161,10 +159,7 @@ export const SourceView = (props: Props) => {
-
+
);
@@ -175,11 +170,7 @@ export const SourceView = (props: Props) => {
style={{ padding: '0' }}
scene={type}
>
-
+
);
}
diff --git a/libs/components/editor-blocks/src/components/source-view/format-url/affine.ts b/libs/components/editor-blocks/src/components/source-view/format-url/affine.ts
index e31e1759cc..37e0c1dcb6 100644
--- a/libs/components/editor-blocks/src/components/source-view/format-url/affine.ts
+++ b/libs/components/editor-blocks/src/components/source-view/format-url/affine.ts
@@ -1,5 +1,5 @@
const _regex =
- /^(https?:\/\/(localhost:4200|(nightly|app)\.affine\.pro|.*?\.ligo-virgo\.pages\.dev)\/\w{28}\/)?(affine\w{16})(\/whiteboard)?$/;
+ /^(https?:\/\/(localhost:4200|(nightly|app|livedemo)\.affine\.pro|.*?\.ligo-virgo\.pages\.dev)\/(\w{28}|AFFiNE)\/)?(affine[\w\-_]{16})(\/edgeless)?$/;
export const isAffineUrl = (url?: string) => {
if (!url) return false;
@@ -7,5 +7,5 @@ export const isAffineUrl = (url?: string) => {
};
export const toAffineEmbedUrl = (url: string) => {
- return _regex.exec(url)?.[4];
+ return _regex.exec(url)?.[5];
};
diff --git a/libs/components/editor-blocks/src/components/source-view/format-url/youtube.ts b/libs/components/editor-blocks/src/components/source-view/format-url/youtube.ts
index ebc0c70be0..56f165a515 100644
--- a/libs/components/editor-blocks/src/components/source-view/format-url/youtube.ts
+++ b/libs/components/editor-blocks/src/components/source-view/format-url/youtube.ts
@@ -1,5 +1,7 @@
export const isYoutubeUrl = (url?: string): boolean => {
- return url.includes('youtu.be') || url.includes('youtube.com');
+ const allowedHosts = ['www.youtu.be', 'www.youtube.com'];
+ const host = new URL(url).host;
+ return allowedHosts.includes(host);
};
const _regexp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#&?]*).*/;
diff --git a/libs/components/editor-blocks/src/components/text-manage/TextManage.tsx b/libs/components/editor-blocks/src/components/text-manage/TextManage.tsx
index f433c1fba9..e42a85c5ed 100644
--- a/libs/components/editor-blocks/src/components/text-manage/TextManage.tsx
+++ b/libs/components/editor-blocks/src/components/text-manage/TextManage.tsx
@@ -4,10 +4,7 @@ import {
type SlateUtils,
type TextProps,
} from '@toeverything/components/common';
-import {
- useOnSelectActive,
- useOnSelectSetSelection,
-} from '@toeverything/components/editor-core';
+import { useOnSelectActive } from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
import { ContentColumnValue } from '@toeverything/datasource/db-service';
import {
@@ -119,15 +116,6 @@ export const TextManage = forwardRef
(
const properties = block.getProperties();
- const onTextViewSetSelection = (selection: Range | Point) => {
- if (selection instanceof Point) {
- //do some thing
- } else {
- textRef.current.setSelection(selection);
- }
- };
-
- // block = await editor.commands.blockCommands.createNextBlock(block.id,)
const onTextViewActive = useCallback(
(point: CursorTypes) => {
// TODO code to be optimized
@@ -209,7 +197,6 @@ export const TextManage = forwardRef(
);
useOnSelectActive(block.id, onTextViewActive);
- useOnSelectSetSelection<'Range'>(block.id, onTextViewSetSelection);
useEffect(() => {
if (textRef.current) {
diff --git a/libs/components/editor-blocks/src/utils/WithTreeViewChildren.tsx b/libs/components/editor-blocks/src/utils/WithTreeViewChildren.tsx
index f4fdd29240..e7e497f2ef 100644
--- a/libs/components/editor-blocks/src/utils/WithTreeViewChildren.tsx
+++ b/libs/components/editor-blocks/src/utils/WithTreeViewChildren.tsx
@@ -1,9 +1,9 @@
import {
+ BlockPendantProvider,
CreateView,
RenderBlock,
useCurrentView,
useOnSelect,
- BlockPendantProvider,
} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
import type {
@@ -60,8 +60,8 @@ const ChildrenView = ({
{childrenIds.map((childId, idx) => {
if (isKanbanScene) {
return (
-
-
+
+
);
}
diff --git a/libs/components/editor-blocks/src/utils/indent.ts b/libs/components/editor-blocks/src/utils/indent.ts
index a68dd5b2db..2c3eee6719 100644
--- a/libs/components/editor-blocks/src/utils/indent.ts
+++ b/libs/components/editor-blocks/src/utils/indent.ts
@@ -1,4 +1,7 @@
-import { supportChildren } from '@toeverything/components/editor-core';
+import {
+ supportChildren,
+ type BlockEditor,
+} from '@toeverything/components/editor-core';
import { Protocol } from '@toeverything/datasource/db-service';
import { AsyncBlock } from '@toeverything/framework/virgo';
import type { TodoAsyncBlock } from '../blocks/todo/types';
@@ -6,14 +9,19 @@ import type { TodoAsyncBlock } from '../blocks/todo/types';
/**
* Is the block in top level
*/
-export const isTopLevelBlock = (parentBlock: AsyncBlock): boolean => {
+export const isTopLevelBlock = (
+ editor: BlockEditor,
+ block: AsyncBlock
+): boolean => {
return (
- parentBlock.type === Protocol.Block.Type.group ||
- parentBlock.type === Protocol.Block.Type.page
+ editor.getRootBlockId() === block.id ||
+ block.type === Protocol.Block.Type.group ||
+ block.type === Protocol.Block.Type.page
);
};
/**
+ * Move down
* @returns true if indent is success
* @example
* ```
@@ -31,7 +39,6 @@ export const isTopLevelBlock = (parentBlock: AsyncBlock): boolean => {
* ```
*/
const indentBlock = async (block: TodoAsyncBlock) => {
- // Move down
const previousBlock = await block.previousSibling();
if (!previousBlock || !supportChildren(previousBlock)) {
@@ -57,6 +64,7 @@ const indentBlock = async (block: TodoAsyncBlock) => {
};
/**
+ * Move up
* @returns true if dedent is success
* @example
* ```
@@ -73,13 +81,15 @@ const indentBlock = async (block: TodoAsyncBlock) => {
* └─ [ ]
* ```
*/
-const dedentBlock = async (block: AsyncBlock) => {
- // Move up
+export const dedentBlock = async (editor: BlockEditor, block: AsyncBlock) => {
+ if (editor.getRootBlockId() === block.id) {
+ return false;
+ }
let parentBlock = await block.parent();
if (!parentBlock) {
throw new Error('Failed to dedent block! Parent block not found!');
}
- if (isTopLevelBlock(parentBlock)) {
+ if (isTopLevelBlock(editor, parentBlock)) {
// Top, do nothing
return false;
}
@@ -111,9 +121,13 @@ const dedentBlock = async (block: AsyncBlock) => {
return true;
};
-export const tabBlock = async (block: AsyncBlock, isShiftKey: boolean) => {
+export const tabBlock = async (
+ editor: BlockEditor,
+ block: AsyncBlock,
+ isShiftKey: boolean
+) => {
if (isShiftKey) {
- return await dedentBlock(block);
+ return await dedentBlock(editor, block);
} else {
return await indentBlock(block);
}
diff --git a/libs/components/editor-core/src/RenderRoot.tsx b/libs/components/editor-core/src/RenderRoot.tsx
index 93ae57a6f0..cbafd3ea75 100644
--- a/libs/components/editor-core/src/RenderRoot.tsx
+++ b/libs/components/editor-core/src/RenderRoot.tsx
@@ -1,16 +1,16 @@
-import type { BlockEditor } from './editor';
import { styled, usePatchNodes } from '@toeverything/components/ui';
-import type { PropsWithChildren } from 'react';
-import React, { useEffect, useRef, useState, useCallback } from 'react';
-import { EditorProvider } from './Contexts';
-import { SelectionRect, SelectionRef } from './Selection';
import {
Protocol,
services,
type ReturnUnobserve,
} from '@toeverything/datasource/db-service';
-import { addNewGroup, appendNewGroup } from './recast-block';
+import type { PropsWithChildren } from 'react';
+import React, { useCallback, useEffect, useRef, useState } from 'react';
+import { EditorProvider } from './Contexts';
+import type { BlockEditor } from './editor';
import { useIsOnDrag } from './hooks';
+import { addNewGroup, appendNewGroup } from './recast-block';
+import { SelectionRect, SelectionRef } from './Selection';
interface RenderRootProps {
editor: BlockEditor;
@@ -160,7 +160,7 @@ export const RenderRoot = ({
return (
{
if (ref != null && ref !== editor.container) {
editor.container = ref;
@@ -188,7 +188,7 @@ export const RenderRoot = ({
{/** TODO: remove selectionManager insert */}
{editor && }
- {editor.isWhiteboard ? null : }
+ {editor.isEdgeless ? null : }
{patchedNodes}
@@ -262,16 +262,10 @@ function ScrollBlank({ editor }: { editor: BlockEditor }) {
const PADDING_X = 150;
const Container = styled('div')(
- ({
- isWhiteboard,
- isOnDrag,
- }: {
- isWhiteboard: boolean;
- isOnDrag: boolean;
- }) => ({
+ ({ isEdgeless, isOnDrag }: { isEdgeless: boolean; isOnDrag: boolean }) => ({
width: '100%',
- padding: isWhiteboard ? 0 : `72px ${PADDING_X}px 0 ${PADDING_X}px`,
- minWidth: isWhiteboard ? 'unset' : '940px',
+ padding: isEdgeless ? 0 : `72px ${PADDING_X}px 0 ${PADDING_X}px`,
+ minWidth: isEdgeless ? 'unset' : '940px',
position: 'relative',
...(isOnDrag && {
cursor: 'grabbing',
diff --git a/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx b/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx
index 955cbc5b9f..6d099d8ae4 100644
--- a/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx
+++ b/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx
@@ -31,7 +31,7 @@ export const BlockPendantProvider = ({
diff --git a/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx b/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx
index 3efc36721f..d66aa0a706 100644
--- a/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx
+++ b/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx
@@ -117,7 +117,7 @@ export const PendantHistoryPanel = ({
/>
}
trigger="click"
- container={historyPanelRef.current}
+ // container={historyPanelRef.current}
>
{
popperHandlerRef={ref => {
popoverHandlerRef.current[id] = ref;
}}
- container={blockRenderContainerRef.current}
+ // container={blockRenderContainerRef.current}
key={id}
trigger="click"
placement="bottom-start"
diff --git a/libs/components/editor-core/src/editor/block/async-block.ts b/libs/components/editor-core/src/editor/block/async-block.ts
index df2f6d972c..73db5de087 100644
--- a/libs/components/editor-core/src/editor/block/async-block.ts
+++ b/libs/components/editor-core/src/editor/block/async-block.ts
@@ -1,19 +1,19 @@
/* eslint-disable max-lines */
-import EventEmitter from 'eventemitter3';
import {
- ReturnEditorBlock,
- UpdateEditorBlock,
DefaultColumnsValue,
Protocol,
+ ReturnEditorBlock,
+ UpdateEditorBlock,
} from '@toeverything/datasource/db-service';
import {
- isDev,
createNoopWithMessage,
- lowerFirst,
+ isDev,
last,
+ lowerFirst,
} from '@toeverything/utils';
-import { BlockProvider } from './block-provider';
+import EventEmitter from 'eventemitter3';
import { BaseView, BaseView as BlockView } from './../views/base-view';
+import { BlockProvider } from './block-provider';
type EventType = 'update';
export interface EventData {
@@ -154,6 +154,7 @@ export class AsyncBlock {
}
this.initialized = true;
this.raw_data = await this.filterPageInvalidChildren(this.raw_data);
+ this.raw_data = await this.updateDoubleLinkBlock(this.raw_data);
const { workspace, id } = this.raw_data;
this.unobserve = await this.services.observe(
{ workspace, id },
@@ -161,6 +162,7 @@ export class AsyncBlock {
const oldData = this.raw_data;
this.raw_data = blockData;
this.raw_data = await this.filterPageInvalidChildren(blockData);
+ this.raw_data = await this.updateDoubleLinkBlock(this.raw_data);
this.emit('update', { block: this, oldData });
}
);
@@ -495,4 +497,33 @@ export class AsyncBlock {
getBoundingClientRect() {
return this.dom?.getBoundingClientRect();
}
+
+ async updateDoubleLinkBlock(rawData: ReturnEditorBlock) {
+ const values = rawData.properties?.text?.value || [];
+ for (let i = 0; i < values.length; i++) {
+ const item = values[i] as any;
+ if (item.linkType === 'doubleLink') {
+ const linkBlock = await this.services.load({
+ workspace: item.workspaceId,
+ id: item.blockId,
+ });
+
+ let children = linkBlock?.getProperties().text?.value || [];
+ if (children.length === 1 && !children[0].text) {
+ children = [{ text: 'Untitled' }];
+ }
+ if (
+ children.map(v => v.text).join('') !==
+ (item.children || []).map((v: any) => v.text).join('')
+ ) {
+ const newItem = {
+ ...item,
+ children: children,
+ };
+ values.splice(i, 1, newItem);
+ }
+ }
+ }
+ return rawData;
+ }
}
diff --git a/libs/components/editor-core/src/editor/block/block-helper.ts b/libs/components/editor-core/src/editor/block/block-helper.ts
index 7bd0284ffc..012633b813 100644
--- a/libs/components/editor-core/src/editor/block/block-helper.ts
+++ b/libs/components/editor-core/src/editor/block/block-helper.ts
@@ -19,6 +19,11 @@ type TextUtilsFunctions =
| 'setSearchSlash'
| 'removeSearchSlash'
| 'getSearchSlashText'
+ | 'setDoubleLinkSearchSlash'
+ | 'getDoubleLinkSearchSlashText'
+ | 'setSelectDoubleLinkSearchSlash'
+ | 'removeDoubleLinkSearchSlash'
+ | 'insertDoubleLink'
| 'selectionToSlateRange'
| 'transformPoint'
| 'toggleTextFormatBySelection'
@@ -32,7 +37,6 @@ type TextUtilsFunctions =
| 'getCommentsIdsBySelection'
| 'getCurrentSelection'
| 'removeSelection'
- | 'insertReference'
| 'isCollapsed'
| 'blur'
| 'setSelection'
@@ -149,27 +153,60 @@ export class BlockHelper {
}
}
- public insertReference(
- reference: string,
+ public setDoubleLinkSearchSlash(blockId: string, point: Point) {
+ const textUtils = this._blockTextUtilsMap[blockId];
+ if (textUtils) {
+ textUtils.setDoubleLinkSearchSlash(point);
+ } else {
+ console.warn('Could find the block text utils');
+ }
+ }
+
+ public getDoubleLinkSearchSlashText(blockId: string) {
+ const textUtils = this._blockTextUtilsMap[blockId];
+ if (textUtils) {
+ return textUtils.getDoubleLinkSearchSlashText();
+ }
+ console.warn('Could find the block text utils');
+ return '';
+ }
+ public setSelectDoubleLinkSearchSlash(blockId: string) {
+ const textUtils = this._blockTextUtilsMap[blockId];
+ if (textUtils) {
+ return textUtils.setSelectDoubleLinkSearchSlash();
+ }
+ console.warn('Could find the block text utils');
+ return '';
+ }
+
+ public removeDoubleLinkSearchSlash(
blockId: string,
- selection: Selection,
- offset: number
+ isRemoveSlash?: boolean
) {
- const text_utils = this._blockTextUtilsMap[blockId];
- if (text_utils) {
- const offsetSelection = window.getSelection();
- offsetSelection.setBaseAndExtent(
- selection.anchorNode,
- selection.anchorOffset,
- selection.focusNode,
- selection.focusOffset + offset
- );
+ const textUtils = this._blockTextUtilsMap[blockId];
+ if (textUtils) {
+ textUtils.removeDoubleLinkSearchSlash(isRemoveSlash);
+ } else {
+ console.warn('Could find the block text utils');
+ }
+ }
- text_utils.removeSelection(offsetSelection);
- text_utils.insertReference(reference);
-
- // range.
- // text_utils.toggleTextFormatBySelection(format, range);
+ public async insertDoubleLink(
+ workspaceId: string,
+ linkBlockId: string,
+ blockId: string
+ ) {
+ const textUtils = this._blockTextUtilsMap[blockId];
+ if (textUtils) {
+ const linkBlock = await this._editor.getBlock({
+ workspace: workspaceId,
+ id: linkBlockId,
+ });
+ let children = linkBlock.getProperties().text?.value || [];
+ if (children.length === 1 && !children[0].text) {
+ children = [{ text: 'Untitled' }];
+ }
+ textUtils.insertDoubleLink(workspaceId, linkBlockId, children);
}
console.warn('Could find the block text utils');
}
diff --git a/libs/components/editor-core/src/editor/clipboard/browser-clipboard.ts b/libs/components/editor-core/src/editor/clipboard/browser-clipboard.ts
index 64eecbc5ca..687c5280ee 100644
--- a/libs/components/editor-core/src/editor/clipboard/browser-clipboard.ts
+++ b/libs/components/editor-core/src/editor/clipboard/browser-clipboard.ts
@@ -1,18 +1,6 @@
import { HooksRunner } from '../types';
-import {
- OFFICE_CLIPBOARD_MIMETYPE,
- InnerClipInfo,
- ClipBlockInfo,
-} from './types';
import { Editor } from '../editor';
-import { AsyncBlock } from '../block';
import ClipboardParse from './clipboard-parse';
-import { SelectInfo } from '../selection';
-import {
- Protocol,
- BlockFlavorKeys,
- services,
-} from '@toeverything/datasource/db-service';
import { MarkdownParser } from './markdown-parse';
import { shouldHandlerContinue } from './utils';
import { Paste } from './paste';
diff --git a/libs/components/editor-core/src/editor/clipboard/clipboard-populator.ts b/libs/components/editor-core/src/editor/clipboard/clipboard-populator.ts
index 2f05866ab9..d7a8172566 100644
--- a/libs/components/editor-core/src/editor/clipboard/clipboard-populator.ts
+++ b/libs/components/editor-core/src/editor/clipboard/clipboard-populator.ts
@@ -1,23 +1,16 @@
import { Editor } from '../editor';
-import { SelectionManager, SelectInfo, SelectBlock } from '../selection';
+import { SelectionManager } from '../selection';
import { HookType, PluginHooks } from '../types';
-import {
- ClipBlockInfo,
- OFFICE_CLIPBOARD_MIMETYPE,
- InnerClipInfo,
-} from './types';
-import { Clip } from './clip';
-import assert from 'assert';
import ClipboardParse from './clipboard-parse';
import { Subscription } from 'rxjs';
-
+import { Copy } from './copy';
class ClipboardPopulator {
private _editor: Editor;
private _hooks: PluginHooks;
private _selectionManager: SelectionManager;
private _clipboardParse: ClipboardParse;
private _sub = new Subscription();
-
+ private _copy: Copy;
constructor(
editor: Editor,
hooks: PluginHooks,
@@ -27,128 +20,15 @@ class ClipboardPopulator {
this._hooks = hooks;
this._selectionManager = selectionManager;
this._clipboardParse = new ClipboardParse(editor);
+ this._copy = new Copy(editor);
this._sub.add(
- hooks
- .get(HookType.BEFORE_COPY)
- .subscribe(this._populateAppClipboard)
+ hooks.get(HookType.BEFORE_COPY).subscribe(this._copy.handleCopy)
);
this._sub.add(
- hooks.get(HookType.BEFORE_CUT).subscribe(this._populateAppClipboard)
+ hooks.get(HookType.BEFORE_CUT).subscribe(this._copy.handleCopy)
);
}
- private _populateAppClipboard = async (e: ClipboardEvent) => {
- e.preventDefault();
- e.stopPropagation();
- const clips = await this.getClips();
- if (!clips.length) {
- return;
- }
-
- // TODO: is not compatible with safari
- const success = this._copyToClipboardFromPc(clips);
- if (!success) {
- // This way, not compatible with firefox
- const clipboardData = e.clipboardData;
- if (clipboardData) {
- try {
- clips.forEach(clip => {
- clipboardData.setData(
- clip.getMimeType(),
- clip.getData()
- );
- });
- } catch (e) {
- // TODO handle exception
- }
- }
- }
- };
-
- private _copyToClipboardFromPc(clips: any[]) {
- let success = false;
- const tempElem = document.createElement('textarea');
- tempElem.value = 'temp';
- document.body.appendChild(tempElem);
- tempElem.select();
- tempElem.setSelectionRange(0, tempElem.value.length);
-
- const listener = function (e: any) {
- const clipboardData = e.clipboardData;
- if (clipboardData) {
- clips.forEach(clip => {
- clipboardData.setData(clip.getMimeType(), clip.getData());
- });
- }
-
- e.preventDefault();
- e.stopPropagation();
- tempElem.removeEventListener('copy', listener);
- } as any;
-
- tempElem.addEventListener('copy', listener);
- try {
- success = document.execCommand('copy');
- } finally {
- tempElem.removeEventListener('copy', listener);
- document.body.removeChild(tempElem);
- }
- return success;
- }
-
- private async _getClipBlockInfo(selBlock: SelectBlock) {
- const block = await this._editor.getBlockById(selBlock.blockId);
- const blockView = this._editor.getView(block.type);
- assert(blockView);
- const blockInfo: ClipBlockInfo = {
- type: block.type,
- properties: blockView.getSelProperties(block, selBlock),
- children: [] as any[],
- };
-
- for (let i = 0; i < selBlock.children.length; i++) {
- const childInfo = await this._getClipBlockInfo(
- selBlock.children[i]
- );
- blockInfo.children.push(childInfo);
- }
-
- return blockInfo;
- }
-
- private async _getInnerClip(): Promise {
- const clips: ClipBlockInfo[] = [];
- const selectInfo: SelectInfo =
- await this._selectionManager.getSelectInfo();
- for (let i = 0; i < selectInfo.blocks.length; i++) {
- const selBlock = selectInfo.blocks[i];
- const clipBlockInfo = await this._getClipBlockInfo(selBlock);
- clips.push(clipBlockInfo);
- }
- return {
- select: selectInfo,
- data: clips,
- };
- }
-
- async getClips() {
- const clips: any[] = [];
-
- const innerClip = await this._getInnerClip();
- clips.push(
- new Clip(
- OFFICE_CLIPBOARD_MIMETYPE.DOCS_DOCUMENT_SLICE_CLIP_WRAPPED,
- JSON.stringify(innerClip)
- )
- );
-
- const htmlClip = await this._clipboardParse.generateHtml();
- htmlClip &&
- clips.push(new Clip(OFFICE_CLIPBOARD_MIMETYPE.HTML, htmlClip));
-
- return clips;
- }
-
disposeInternal() {
this._sub.unsubscribe();
this._hooks = null;
diff --git a/libs/components/editor-core/src/editor/clipboard/copy.ts b/libs/components/editor-core/src/editor/clipboard/copy.ts
new file mode 100644
index 0000000000..94b3117264
--- /dev/null
+++ b/libs/components/editor-core/src/editor/clipboard/copy.ts
@@ -0,0 +1,102 @@
+import { Editor } from '../editor';
+import { SelectInfo } from '../selection';
+import { OFFICE_CLIPBOARD_MIMETYPE } from './types';
+import { Clip } from './clip';
+import ClipboardParse from './clipboard-parse';
+import { getClipDataOfBlocksById } from './utils';
+import { copyToClipboard } from '@toeverything/utils';
+class Copy {
+ private _editor: Editor;
+ private _clipboardParse: ClipboardParse;
+
+ constructor(editor: Editor) {
+ this._editor = editor;
+ this._clipboardParse = new ClipboardParse(editor);
+
+ this.handleCopy = this.handleCopy.bind(this);
+ }
+ public async handleCopy(e: ClipboardEvent) {
+ e.preventDefault();
+ e.stopPropagation();
+ const clips = await this.getClips();
+ if (!clips.length) {
+ return;
+ }
+ // TODO: is not compatible with safari
+ const success = this._copyToClipboardFromPc(clips);
+ if (!success) {
+ // This way, not compatible with firefox
+ const clipboardData = e.clipboardData;
+ if (clipboardData) {
+ try {
+ clips.forEach(clip => {
+ clipboardData.setData(
+ clip.getMimeType(),
+ clip.getData()
+ );
+ });
+ } catch (e) {
+ // TODO handle exception
+ }
+ }
+ }
+ }
+
+ async getClips() {
+ const clips: Clip[] = [];
+
+ // get custom clip
+ const affineClip = await this._getAffineClip();
+ clips.push(affineClip);
+
+ // get common html clip
+ const htmlClip = await this._clipboardParse.generateHtml();
+ htmlClip &&
+ clips.push(new Clip(OFFICE_CLIPBOARD_MIMETYPE.HTML, htmlClip));
+
+ return clips;
+ }
+
+ private async _getAffineClip(): Promise {
+ const selectInfo: SelectInfo =
+ await this._editor.selectionManager.getSelectInfo();
+
+ return getClipDataOfBlocksById(
+ this._editor,
+ selectInfo.blocks.map(block => block.blockId)
+ );
+ }
+
+ private _copyToClipboardFromPc(clips: any[]) {
+ let success = false;
+ const tempElem = document.createElement('textarea');
+ tempElem.value = 'temp';
+ document.body.appendChild(tempElem);
+ tempElem.select();
+ tempElem.setSelectionRange(0, tempElem.value.length);
+
+ const listener = function (e: any) {
+ const clipboardData = e.clipboardData;
+ if (clipboardData) {
+ clips.forEach(clip => {
+ clipboardData.setData(clip.getMimeType(), clip.getData());
+ });
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+ tempElem.removeEventListener('copy', listener);
+ } as any;
+
+ tempElem.addEventListener('copy', listener);
+ try {
+ success = document.execCommand('copy');
+ } finally {
+ tempElem.removeEventListener('copy', listener);
+ document.body.removeChild(tempElem);
+ }
+ return success;
+ }
+}
+
+export { Copy };
diff --git a/libs/components/editor-core/src/editor/clipboard/paste.ts b/libs/components/editor-core/src/editor/clipboard/paste.ts
index b24d06b23a..37168c2614 100644
--- a/libs/components/editor-core/src/editor/clipboard/paste.ts
+++ b/libs/components/editor-core/src/editor/clipboard/paste.ts
@@ -241,15 +241,12 @@ export class Paste {
[]
);
- selectedBlock.setProperties({
+ await selectedBlock.setProperties({
text: {
value: newTextValue,
},
});
- const pasteBlocks = await this._createBlocks(blocks);
- await Promise.all(
- pasteBlocks.map(block => selectedBlock.after(block))
- );
+ const pastedBlocks = await this._createBlocks(blocks);
const nextBlock = await this._editor.createBlock(
selectedBlock?.type
@@ -259,11 +256,12 @@ export class Paste {
value: nextTextValue,
},
});
- pasteBlocks[pasteBlocks.length - 1].after(nextBlock);
- this._setEndSelectToBlock(
- pasteBlocks[pasteBlocks.length - 1].id
- );
+ await this._insertBlocksAfterBlock(selectedBlock, [
+ ...pastedBlocks,
+ nextBlock,
+ ]);
+ await this._setEndSelectToBlock(nextBlock.id);
} else {
this._editor.blockHelper.insertNodes(
selectedBlock.id,
@@ -327,10 +325,7 @@ export class Paste {
value: newTextValue,
},
});
- const pasteBlocks = await this._createBlocks(blocks);
- pasteBlocks.forEach((block: AsyncBlock) => {
- selectedBlock.after(block);
- });
+ const pastedBlocks = await this._createBlocks(blocks);
const nextBlock = await this._editor.createBlock(
selectedBlock?.type
);
@@ -339,11 +334,12 @@ export class Paste {
value: nextTextValue,
},
});
- pasteBlocks[pasteBlocks.length - 1].after(nextBlock);
+ await this._insertBlocksAfterBlock(selectedBlock, [
+ ...pastedBlocks,
+ nextBlock,
+ ]);
- this._setEndSelectToBlock(
- pasteBlocks[pasteBlocks.length - 1].id
- );
+ await this._setEndSelectToBlock(nextBlock.id);
} else {
this._editor.blockHelper.insertNodes(
selectedBlock.id,
@@ -353,10 +349,10 @@ export class Paste {
}
}
} else {
- const pasteBlocks = await this._createBlocks(blocks);
+ const pastedBlocks = await this._createBlocks(blocks);
await Promise.all(
- pasteBlocks.map(block => selectedBlock.after(block))
+ pastedBlocks.map(block => selectedBlock.after(block))
);
if (isSelectedBlockEmpty) {
@@ -364,7 +360,7 @@ export class Paste {
}
this._setEndSelectToBlock(
- pasteBlocks[pasteBlocks.length - 1].id
+ pastedBlocks[pastedBlocks.length - 1].id
);
}
}
@@ -374,27 +370,39 @@ export class Paste {
currentSelectInfo.blocks[currentSelectInfo.blocks.length - 1]
.blockId
);
- const pasteBlocks = await this._createBlocks(blocks);
+ const pastedBlocks = await this._createBlocks(blocks);
let groupBlock: AsyncBlock;
- if (
- selectedBlock?.type === 'group' ||
- selectedBlock?.type === 'page'
- ) {
+ if (selectedBlock?.type === 'page') {
groupBlock = await this._editor.createBlock('group');
await Promise.all(
- pasteBlocks.map(block => groupBlock.append(block))
+ pastedBlocks.map(block => groupBlock.append(block))
);
await selectedBlock.after(groupBlock);
+ } else if (selectedBlock?.type === 'group') {
+ await Promise.all(
+ pastedBlocks.map(block => selectedBlock.append(block))
+ );
} else {
await Promise.all(
- pasteBlocks.map(block => selectedBlock.after(block))
+ pastedBlocks.map(block => selectedBlock.after(block))
);
}
- this._setEndSelectToBlock(pasteBlocks[pasteBlocks.length - 1].id);
+ this._setEndSelectToBlock(pastedBlocks[pastedBlocks.length - 1].id);
}
}
+ private async _insertBlocksAfterBlock(
+ targetBlock: AsyncBlock,
+ blocks: AsyncBlock[]
+ ) {
+ if (blocks.length === 0) {
+ return;
+ }
+ const [firstBlock, ...otherBlock] = blocks;
+ await targetBlock.after(firstBlock);
+ await this._insertBlocksAfterBlock(blocks[0], otherBlock);
+ }
private async _setEndSelectToBlock(blockId: string) {
const block = await this._editor.getBlockById(blockId);
const isBlockCanEdit = Paste._isTextEditBlock(block.type);
@@ -406,14 +414,37 @@ export class Paste {
}, 100);
}
- private async _createBlocks(blocks: ClipBlockInfo[], parentId?: string) {
+ private _flatGroupBlocks(blocks: ClipBlockInfo[]) {
+ return blocks.reduce(
+ (blockList: ClipBlockInfo[], block: ClipBlockInfo) => {
+ if (block.type === 'group') {
+ block?.children?.forEach(childBlock => {
+ childBlock.children = this._flatGroupBlocks(
+ childBlock.children
+ );
+ });
+ block?.children?.length &&
+ blockList.push(...block.children);
+ } else {
+ blockList.push(block);
+ block.children = this._flatGroupBlocks(block.children);
+ }
+ return blockList;
+ },
+ []
+ );
+ }
+ private async _createBlocks(blocks: ClipBlockInfo[]) {
return Promise.all(
- blocks.map(async clipBlockInfo => {
+ this._flatGroupBlocks(blocks).map(async clipBlockInfo => {
const block = await this._editor.createBlock(
clipBlockInfo.type
);
block?.setProperties(clipBlockInfo.properties);
- await this._createBlocks(clipBlockInfo.children, block?.id);
+ const children = await this._createBlocks(
+ clipBlockInfo.children
+ );
+ await Promise.all(children.map(child => block?.append(child)));
return block;
})
);
diff --git a/libs/components/editor-core/src/editor/clipboard/utils.ts b/libs/components/editor-core/src/editor/clipboard/utils.ts
index cb5d10241e..c807a869a0 100644
--- a/libs/components/editor-core/src/editor/clipboard/utils.ts
+++ b/libs/components/editor-core/src/editor/clipboard/utils.ts
@@ -1,4 +1,6 @@
import { Editor } from '../editor';
+import { ClipBlockInfo, OFFICE_CLIPBOARD_MIMETYPE } from './types';
+import { Clip } from './clip';
export const shouldHandlerContinue = (event: Event, editor: Editor) => {
const filterNodes = ['INPUT', 'SELECT', 'TEXTAREA'];
@@ -12,3 +14,39 @@ export const shouldHandlerContinue = (event: Event, editor: Editor) => {
return editor.selectionManager.currentSelectInfo.type !== 'None';
};
+
+export const getClipInfoOfBlockById = async (
+ editor: Editor,
+ blockId: string
+) => {
+ const block = await editor.getBlockById(blockId);
+ const blockView = editor.getView(block.type);
+ const blockInfo: ClipBlockInfo = {
+ type: block.type,
+ properties: blockView.getSelProperties(block, {}),
+ children: [] as ClipBlockInfo[],
+ };
+ const children = (await block?.children()) ?? [];
+
+ for (let i = 0; i < children.length; i++) {
+ const childInfo = await getClipInfoOfBlockById(editor, children[i].id);
+ blockInfo.children.push(childInfo);
+ }
+ return blockInfo;
+};
+
+export const getClipDataOfBlocksById = async (
+ editor: Editor,
+ blockIds: string[]
+) => {
+ const clipInfos = await Promise.all(
+ blockIds.map(blockId => getClipInfoOfBlockById(editor, blockId))
+ );
+
+ return new Clip(
+ OFFICE_CLIPBOARD_MIMETYPE.DOCS_DOCUMENT_SLICE_CLIP_WRAPPED,
+ JSON.stringify({
+ data: clipInfos,
+ })
+ );
+};
diff --git a/libs/components/editor-core/src/editor/drag-drop/drag-drop.ts b/libs/components/editor-core/src/editor/drag-drop/drag-drop.ts
index 9da0ed55ee..a96de8eb93 100644
--- a/libs/components/editor-core/src/editor/drag-drop/drag-drop.ts
+++ b/libs/components/editor-core/src/editor/drag-drop/drag-drop.ts
@@ -1,4 +1,5 @@
/* eslint-disable max-lines */
+import { Protocol } from '@toeverything/datasource/db-service';
import { domToRect, Point } from '@toeverything/utils';
import { AsyncBlock } from '../..';
import { GridDropType } from '../commands/types';
@@ -6,7 +7,6 @@ import { Editor } from '../editor';
import { BlockDropPlacement, GroupDirection } from '../types';
// TODO: Evaluate implementing custom events with Rxjs
import EventEmitter from 'eventemitter3';
-import { Protocol } from '@toeverything/datasource/db-service';
enum DragType {
dragBlock = 'dragBlock',
@@ -281,6 +281,10 @@ export class DragDropManager {
this._editor.getRootBlockId()
);
let direction = BlockDropPlacement.none;
+ if (!rootBlock || !rootBlock.dom) {
+ console.warn('Can not find dom bind with block', rootBlock);
+ return;
+ }
const rootBlockRect = domToRect(rootBlock.dom);
let targetBlock: AsyncBlock | undefined;
let typesInfo = {
@@ -303,6 +307,10 @@ export class DragDropManager {
if (direction !== BlockDropPlacement.none) {
const blockList = await this._editor.getBlockListByLevelOrder();
targetBlock = blockList.find(block => {
+ if (!block.dom) {
+ console.warn('Can not find dom bind with block', block);
+ return false;
+ }
const domRect = domToRect(block.dom);
const pointChecker =
direction === BlockDropPlacement.outerLeft
diff --git a/libs/components/editor-core/src/editor/editor.ts b/libs/components/editor-core/src/editor/editor.ts
index 24854735f4..e7f6458a5f 100644
--- a/libs/components/editor-core/src/editor/editor.ts
+++ b/libs/components/editor-core/src/editor/editor.ts
@@ -1,55 +1,49 @@
/* eslint-disable max-lines */
-import HotKeys from 'hotkeys-js';
-import LRUCache from 'lru-cache';
-
-import { services } from '@toeverything/datasource/db-service';
+import type { PatchNode } from '@toeverything/components/ui';
+import { Commands } from '@toeverything/datasource/commands';
import type {
BlockFlavors,
ReturnEditorBlock,
UpdateEditorBlock,
} from '@toeverything/datasource/db-service';
-import type { PatchNode } from '@toeverything/components/ui';
-
-import { AsyncBlock } from './block';
-import type { WorkspaceAndBlockId } from './block';
-import type { BaseView } from './views/base-view';
-import { SelectionManager } from './selection';
-import { Hooks, PluginManager } from './plugin';
-import { EditorCommands } from './commands';
-import {
- Virgo,
- HooksRunner,
- PluginHooks,
- PluginCreator,
- StorageManager,
- VirgoSelection,
- PluginManagerInterface,
-} from './types';
-import { KeyboardManager } from './keyboard';
-import { MouseManager } from './mouse';
-import { ScrollManager } from './scroll';
-import assert from 'assert';
+import { services } from '@toeverything/datasource/db-service';
import { domToRect, last, Point, sleep } from '@toeverything/utils';
-import { Commands } from '@toeverything/datasource/commands';
+import assert from 'assert';
+import HotKeys from 'hotkeys-js';
+import type { WorkspaceAndBlockId } from './block';
+import { AsyncBlock } from './block';
+import { BlockHelper } from './block/block-helper';
import { BrowserClipboard } from './clipboard/browser-clipboard';
import { ClipboardPopulator } from './clipboard/clipboard-populator';
-import { BlockHelper } from './block/block-helper';
-import { DragDropManager } from './drag-drop';
+import { EditorCommands } from './commands';
import { EditorConfig } from './config';
+import { DragDropManager } from './drag-drop';
+import { KeyboardManager } from './keyboard';
+import { MouseManager } from './mouse';
+import { Hooks, PluginManager } from './plugin';
+import { ScrollManager } from './scroll';
+import { SelectionManager } from './selection';
+import {
+ HooksRunner,
+ PluginCreator,
+ PluginHooks,
+ PluginManagerInterface,
+ StorageManager,
+ Virgo,
+ VirgoSelection,
+} from './types';
+import type { BaseView } from './views/base-view';
export interface EditorCtorProps {
workspace: string;
views: Partial>;
plugins: PluginCreator[];
rootBlockId: string;
- isWhiteboard?: boolean;
+ isEdgeless?: boolean;
}
export class Editor implements Virgo {
- private _cacheManager = new LRUCache>({
- max: 8192,
- ttl: 1000 * 60 * 30,
- });
+ private _cacheManager = new Map>();
public mouseManager = new MouseManager(this);
public selectionManager = new SelectionManager(this);
public keyboardManager = new KeyboardManager(this);
@@ -75,7 +69,7 @@ export class Editor implements Virgo {
render: PatchNode;
has: (key: string) => boolean;
};
- public isWhiteboard = false;
+ public isEdgeless = false;
private _isDisposed = false;
constructor(props: EditorCtorProps) {
@@ -85,8 +79,8 @@ export class Editor implements Virgo {
this.hooks = new Hooks();
this.plugin_manager = new PluginManager(this, this.hooks);
this.plugin_manager.registerAll(props.plugins);
- if (props.isWhiteboard) {
- this.isWhiteboard = true;
+ if (props.isEdgeless) {
+ this.isEdgeless = true;
}
for (const [name, block] of Object.entries(props.views)) {
services.api.editorBlock.registerContentExporter(
@@ -148,18 +142,41 @@ export class Editor implements Virgo {
public get container() {
return this.ui_container;
}
- // preference to use withSuspend
+
+ /**
+ * Use it discreetly.
+ * Preference to use {@link withBatch}
+ */
public suspend(flag: boolean) {
services.api.editorBlock.suspend(this.workspace, flag);
}
- public async withSuspend any>(
+ // TODO support suspend recursion
+ private _isSuspend = false;
+ public withBatch Promise>(fn: T): T {
+ return (async (...args) => {
+ if (this._isSuspend) {
+ console.warn(
+ 'The editor currently has suspend! Please do not call batch method repeatedly!'
+ );
+ }
+ this._isSuspend = true;
+ services.api.editorBlock.suspend(this.workspace, true);
+ const result = await fn(...args);
+ services.api.editorBlock.suspend(this.workspace, false);
+ this._isSuspend = false;
+ return result;
+ }) as T;
+ }
+
+ /**
+ * Use it discreetly.
+ * Preference to use {@link withBatch}
+ */
+ public async batch any>(
fn: T
): Promise>> {
- services.api.editorBlock.suspend(this.workspace, true);
- const result = await fn();
- services.api.editorBlock.suspend(this.workspace, false);
- return result;
+ return this.withBatch(fn)();
}
public setReactRenderRoot(props: {
@@ -211,7 +228,12 @@ export class Editor implements Virgo {
return await services.api.editorBlock.update(patches);
},
remove: async ({ workspace, id }: WorkspaceAndBlockId) => {
- return await services.api.editorBlock.delete({ workspace, id });
+ const ret = await services.api.editorBlock.delete({
+ workspace,
+ id,
+ });
+ this._cacheManager.delete(id);
+ return ret;
},
observe: async (
{ workspace, id }: WorkspaceAndBlockId,
@@ -258,7 +280,7 @@ export class Editor implements Virgo {
return await blockView.onCreate(block);
}
- private async getBlock({
+ public async getBlock({
workspace,
id,
}: WorkspaceAndBlockId): Promise {
diff --git a/libs/components/editor-core/src/editor/index.ts b/libs/components/editor-core/src/editor/index.ts
index 03903d31bf..3131e6f0a1 100644
--- a/libs/components/editor-core/src/editor/index.ts
+++ b/libs/components/editor-core/src/editor/index.ts
@@ -10,3 +10,4 @@ export { BlockDropPlacement, HookType, GroupDirection } from './types';
export type { Plugin, PluginCreator, PluginHooks, Virgo } from './types';
export { BaseView, getTextHtml, getTextProperties } from './views/base-view';
export type { ChildrenView, CreateView } from './views/base-view';
+export { getClipDataOfBlocksById } from './clipboard/utils';
diff --git a/libs/components/editor-core/src/editor/selection/selection.ts b/libs/components/editor-core/src/editor/selection/selection.ts
index 406f9adecb..e6c1f94c83 100644
--- a/libs/components/editor-core/src/editor/selection/selection.ts
+++ b/libs/components/editor-core/src/editor/selection/selection.ts
@@ -1,15 +1,16 @@
/* eslint-disable max-lines */
import {
+ debounce,
domToRect,
+ getBlockIdByDom,
+ last,
Point,
Rect,
- last,
without,
- debounce,
- getBlockIdByDom,
} from '@toeverything/utils';
import EventEmitter from 'eventemitter3';
+import { Protocol } from '@toeverything/datasource/db-service';
import { BlockEditor } from '../..';
import { AsyncBlock } from '../block';
import { VirgoSelection } from '../types';
@@ -18,19 +19,17 @@ import {
changeEventName,
CursorTypes,
IdList,
+ SelectBlock,
selectEndEventName,
SelectEventCallbackTypes,
SelectEventTypes,
+ SelectInfo,
SelectionSettings,
SelectionSettingsMap,
SelectionTypes,
SelectPosition,
- SelectBlock,
- SelectInfo,
} from './types';
import { isLikeBlockListIds } from './utils';
-import { Protocol } from '@toeverything/datasource/db-service';
-import { Editor } from 'slate';
// IMP: maybe merge active and select into single function
export type SelectionInfo = InstanceType<
@@ -336,12 +335,12 @@ export class SelectionManager implements VirgoSelection {
});
for await (const childBlock of selectableChildren) {
const { dom } = childBlock;
- if (dom && selectionRect.isIntersect(domToRect(dom))) {
- selectedNodes.push(childBlock);
- }
if (!dom) {
console.warn('can not find dom bind with block');
}
+ if (dom && selectionRect.isIntersect(domToRect(dom))) {
+ selectedNodes.push(childBlock);
+ }
}
// if just only has one selected maybe select the children
if (selectedNodes.length === 1) {
@@ -1063,10 +1062,10 @@ export class SelectionManager implements VirgoSelection {
index: number,
blockId: string
): Promise {
- let preRang = document.createRange();
+ const preRang = document.createRange();
preRang.setStart(nowRange.startContainer, index);
preRang.setEnd(nowRange.endContainer, index);
- let prePosition = preRang.getClientRects().item(0);
+ const prePosition = preRang.getClientRects().item(0);
this.activeNodeByNodeId(
blockId,
new Point(prePosition.left, prePosition.bottom)
diff --git a/libs/components/editor-core/src/editor/types.ts b/libs/components/editor-core/src/editor/types.ts
index 63732fbba7..1b97cf0f86 100644
--- a/libs/components/editor-core/src/editor/types.ts
+++ b/libs/components/editor-core/src/editor/types.ts
@@ -8,21 +8,17 @@
* 5. All Plugins should inherit from BasePlugin, in the form of objects
* 6. Dependencies between plugins are not supported for the time being
*/
-// import { CompleteInfoSelectOption } from '@authing/react-ui-components/components/CompleteInfo/interface';
-import type {
- BlockFlavors,
- BlockFlavorKeys,
-} from '@toeverything/datasource/db-service';
import type { PatchNode } from '@toeverything/components/ui';
+import type { BlockFlavors } from '@toeverything/datasource/db-service';
import type { IdList, SelectionInfo, SelectionManager } from './selection';
+import { Point } from '@toeverything/utils';
+import { Observable } from 'rxjs';
import type { AsyncBlock } from './block';
import type { BlockHelper } from './block/block-helper';
import type { BlockCommands } from './commands/block-commands';
import type { DragDropManager } from './drag-drop';
import { MouseManager } from './mouse';
-import { Observable } from 'rxjs';
-import { Point } from '@toeverything/utils';
import { ScrollManager } from './scroll';
// import { BrowserClipboard } from './clipboard/browser-clipboard';
@@ -111,7 +107,7 @@ export interface Virgo {
getBlockDomById: (id: string) => Promise;
getBlockByPoint: (point: Point) => Promise;
getGroupBlockByPoint: (point: Point) => Promise;
- isWhiteboard: boolean;
+ isEdgeless: boolean;
mouseManager: MouseManager;
}
diff --git a/libs/components/editor-core/src/editor/views/base-view.ts b/libs/components/editor-core/src/editor/views/base-view.ts
index 4fe50d3b90..eb5c293243 100644
--- a/libs/components/editor-core/src/editor/views/base-view.ts
+++ b/libs/components/editor-core/src/editor/views/base-view.ts
@@ -9,16 +9,15 @@ import {
BlockDecoration,
MapOperation,
} from '@toeverything/datasource/jwt';
+import { cloneDeep } from '@toeverything/utils';
import type { EventData } from '../block';
import { AsyncBlock } from '../block';
import type { Editor } from '../editor';
-import { cloneDeep } from '@toeverything/utils';
import { SelectBlock } from '../selection';
export interface CreateView {
block: AsyncBlock;
editor: Editor;
- editorElement: () => JSX.Element;
/**
* @deprecated Use recast table instead
*/
@@ -114,7 +113,21 @@ export abstract class BaseView {
// Whether the component is empty
isEmpty(block: AsyncBlock): boolean {
const text = block.getProperty('text');
- return !text?.value?.[0]?.text;
+ const result = !text?.value?.[0]?.text;
+
+ // Assert that the text is really empty
+ if (
+ result &&
+ block.getProperty('text')?.value.some(content => content.text)
+ ) {
+ console.warn(
+ 'Assertion isEmpty error! The block has an empty start fragment, but it is not empty',
+ block
+ );
+ }
+ // Assert end
+
+ return result;
}
getSelProperties(block: AsyncBlock, selectInfo: any): DefaultColumnsValue {
diff --git a/libs/components/editor-core/src/index.ts b/libs/components/editor-core/src/index.ts
index bea2fed3a0..d28d8e96b3 100644
--- a/libs/components/editor-core/src/index.ts
+++ b/libs/components/editor-core/src/index.ts
@@ -16,4 +16,4 @@ export * from './utils';
export * from './editor';
-export { RefPageProvider, useRefPage } from './ref-page';
+export { useEditor } from './Contexts';
diff --git a/libs/components/editor-core/src/recast-block/Context.tsx b/libs/components/editor-core/src/recast-block/Context.tsx
index 47ec6cfcdb..4236ede55a 100644
--- a/libs/components/editor-core/src/recast-block/Context.tsx
+++ b/libs/components/editor-core/src/recast-block/Context.tsx
@@ -2,7 +2,6 @@ import { Protocol } from '@toeverything/datasource/db-service';
import { AsyncBlock } from '../editor';
import { ComponentType, createContext, ReactNode, useContext } from 'react';
import { RecastBlock } from './types';
-import { RefPageProvider } from '../ref-page';
/**
* Determine whether the block supports RecastBlock
@@ -48,7 +47,7 @@ export const RecastBlockProvider = ({
return (
- {children}
+ {children}
);
};
diff --git a/libs/components/editor-core/src/recast-block/types/view.ts b/libs/components/editor-core/src/recast-block/types/view.ts
index 3f03187bce..fa30c07861 100644
--- a/libs/components/editor-core/src/recast-block/types/view.ts
+++ b/libs/components/editor-core/src/recast-block/types/view.ts
@@ -7,7 +7,6 @@ export enum RecastScene {
Page = 'page',
Kanban = 'kanban',
Table = 'table',
- // Whiteboard = 'whiteboard',
}
export type RecastViewId = string & {
diff --git a/libs/components/editor-core/src/ref-page/index.ts b/libs/components/editor-core/src/ref-page/index.ts
deleted file mode 100644
index 4b06310a5c..0000000000
--- a/libs/components/editor-core/src/ref-page/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { useRefPage, RefPageProvider } from './ModalPage';
diff --git a/libs/components/editor-core/src/render-block/RenderBlock.tsx b/libs/components/editor-core/src/render-block/RenderBlock.tsx
index a7ebc1e2e1..0a1531a709 100644
--- a/libs/components/editor-core/src/render-block/RenderBlock.tsx
+++ b/libs/components/editor-core/src/render-block/RenderBlock.tsx
@@ -13,7 +13,7 @@ export function RenderBlock({
blockId,
hasContainer = true,
}: RenderBlockProps) {
- const { editor, editorElement } = useEditor();
+ const { editor } = useEditor();
const { block } = useBlock(blockId);
const setRef = useCallback(
@@ -25,11 +25,11 @@ export function RenderBlock({
[block]
);
- const blockView = useMemo(() => {
+ const BlockView = useMemo(() => {
if (block?.type) {
- return editor.getView(block.type);
+ return editor.getView(block.type).View;
}
- return null;
+ return () => null;
}, [editor, block?.type]);
if (!block) {
@@ -44,22 +44,21 @@ export function RenderBlock({
columns: block.columns ?? [],
};
- const view = blockView?.View ? (
-
- ) : null;
+ );
return hasContainer ? (
{view}
) : (
- <> {view}>
+ view
);
}
diff --git a/libs/components/editor-plugins/src/index.ts b/libs/components/editor-plugins/src/index.ts
index be7bb9bd97..4c6ce9a1e1 100644
--- a/libs/components/editor-plugins/src/index.ts
+++ b/libs/components/editor-plugins/src/index.ts
@@ -1,15 +1,15 @@
import type { PluginCreator } from '@toeverything/framework/virgo';
-import {
- LeftMenuPlugin,
- InlineMenuPlugin,
- CommandMenuPlugin,
- ReferenceMenuPlugin,
- SelectionGroupPlugin,
- GroupMenuPlugin,
-} from './menu';
-import { TemplatePlugin } from './template';
-import { FullTextSearchPlugin } from './search';
import { AddCommentPlugin } from './comment';
+import {
+ CommandMenuPlugin,
+ DoubleLinkMenuPlugin,
+ GroupMenuPlugin,
+ InlineMenuPlugin,
+ LeftMenuPlugin,
+ SelectionGroupPlugin,
+} from './menu';
+import { FullTextSearchPlugin } from './search';
+import { TemplatePlugin } from './template';
// import { PlaceholderPlugin } from './placeholder';
// import { BlockPropertyPlugin } from './block-property';
@@ -19,9 +19,9 @@ export const plugins: PluginCreator[] = [
LeftMenuPlugin,
InlineMenuPlugin,
CommandMenuPlugin,
- ReferenceMenuPlugin,
+ DoubleLinkMenuPlugin,
TemplatePlugin,
- SelectionGroupPlugin,
+ // SelectionGroupPlugin,
AddCommentPlugin,
GroupMenuPlugin,
];
diff --git a/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx b/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx
index 7b74cbfd55..2772ec0d41 100644
--- a/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx
+++ b/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx
@@ -1,4 +1,6 @@
+import { MuiClickAwayListener } from '@toeverything/components/ui';
import { BlockFlavorKeys, Protocol } from '@toeverything/datasource/db-service';
+import { HookType, PluginHooks, Virgo } from '@toeverything/framework/virgo';
import React, {
useCallback,
useEffect,
@@ -6,18 +8,15 @@ import React, {
useRef,
useState,
} from 'react';
-
-import { MuiClickAwayListener } from '@toeverything/components/ui';
-import { Virgo, HookType, PluginHooks } from '@toeverything/framework/virgo';
-
-import { CommandMenuContainer } from './Container';
+import { QueryResult } from '../../search';
import {
CommandMenuCategories,
commandMenuHandlerMap,
commonCommandMenuHandler,
menuItemsMap,
} from './config';
-import { QueryResult } from '../../search';
+import { CommandMenuContainer } from './Container';
+
export type CommandMenuProps = {
editor: Virgo;
hooks: PluginHooks;
@@ -225,7 +224,11 @@ export const CommandMenu = ({ editor, hooks, style }: CommandMenuProps) => {
await commonCommandMenuHandler(blockId, type, editor);
}
const block = await editor.getBlockById(blockId);
- block.remove();
+ let nextBlock = await block.nextSibling();
+ editor.selectionManager.activeNodeByNodeId(nextBlock.id);
+ if (block.blockProvider.isEmpty()) {
+ block.remove();
+ }
} else {
if (Protocol.Block.Type[type as BlockFlavorKeys]) {
const block = await editor.commands.blockCommands.convertBlock(
diff --git a/libs/components/editor-plugins/src/menu/double-link-menu/Container.tsx b/libs/components/editor-plugins/src/menu/double-link-menu/Container.tsx
new file mode 100644
index 0000000000..ec5f52be08
--- /dev/null
+++ b/libs/components/editor-plugins/src/menu/double-link-menu/Container.tsx
@@ -0,0 +1,121 @@
+import { CommonList, CommonListItem } from '@toeverything/components/common';
+import { styled } from '@toeverything/components/ui';
+import { HookType, PluginHooks, Virgo } from '@toeverything/framework/virgo';
+import React, { useCallback, useEffect, useRef, useState } from 'react';
+
+export type DoubleLinkMenuContainerProps = {
+ editor: Virgo;
+ hooks: PluginHooks;
+ style?: React.CSSProperties;
+ blockId: string;
+ onSelected?: (item: string) => void;
+ onClose?: () => void;
+ types?: Array;
+ items?: CommonListItem[];
+};
+
+export const DoubleLinkMenuContainer = (
+ props: DoubleLinkMenuContainerProps
+) => {
+ const { hooks, onSelected, onClose, types, style, items } = props;
+ const menuRef = useRef(null);
+ const [currentItem, setCurrentItem] = useState();
+
+ useEffect(() => {
+ if (types && !currentItem) {
+ setCurrentItem(types[0]);
+ }
+ }, [currentItem, onClose, types]);
+
+ const handleUpDownKey = useCallback(
+ (event: React.KeyboardEvent) => {
+ if (types && ['ArrowUp', 'ArrowDown'].includes(event.code)) {
+ event.preventDefault();
+ const isUpkey = event.code === 'ArrowUp';
+ if (!currentItem && types.length) {
+ setCurrentItem(types[isUpkey ? types.length - 1 : 0]);
+ }
+ if (currentItem) {
+ const idx = types.indexOf(currentItem);
+ if (isUpkey ? idx > 0 : idx < types.length - 1) {
+ setCurrentItem(types[isUpkey ? idx - 1 : idx + 1]);
+ }
+ }
+ }
+ },
+ [currentItem, types]
+ );
+ const handleClickUp = useCallback(
+ (event: React.KeyboardEvent) => {
+ handleUpDownKey(event);
+ },
+ [handleUpDownKey]
+ );
+
+ const handleClickDown = useCallback(
+ (event: React.KeyboardEvent) => {
+ handleUpDownKey(event);
+ },
+ [handleUpDownKey]
+ );
+
+ const handleClickEnter = useCallback(
+ async (event: React.KeyboardEvent) => {
+ if (event.code === 'Enter' && currentItem) {
+ event.preventDefault();
+ onSelected && onSelected(currentItem);
+ }
+ },
+ [currentItem, onSelected]
+ );
+
+ const handleKeyDown = useCallback(
+ (event: React.KeyboardEvent) => {
+ handleClickUp(event);
+ handleClickDown(event);
+ handleClickEnter(event);
+ },
+ [handleClickUp, handleClickDown, handleClickEnter]
+ );
+
+ useEffect(() => {
+ const sub = hooks
+ .get(HookType.ON_ROOT_NODE_KEYDOWN_CAPTURE)
+ .subscribe(handleKeyDown);
+
+ return () => {
+ sub.unsubscribe();
+ };
+ }, [hooks, handleKeyDown]);
+
+ return (
+
+
+ onSelected?.(type)}
+ currentItem={currentItem}
+ setCurrentItem={setCurrentItem}
+ />
+
+
+ );
+};
+
+const RootContainer = styled('div')(({ theme }) => ({
+ zIndex: 1,
+ borderRadius: '10px',
+ boxShadow: theme.affine.shadows.shadow1,
+ backgroundColor: '#fff',
+ padding: '8px 4px',
+}));
+
+const ContentContainer = styled('div')(({ theme }) => ({
+ display: 'flex',
+ overflow: 'hidden',
+ maxHeight: '300px',
+}));
diff --git a/libs/components/editor-plugins/src/menu/double-link-menu/DoubleLinkMenu.tsx b/libs/components/editor-plugins/src/menu/double-link-menu/DoubleLinkMenu.tsx
new file mode 100644
index 0000000000..a81e8b3122
--- /dev/null
+++ b/libs/components/editor-plugins/src/menu/double-link-menu/DoubleLinkMenu.tsx
@@ -0,0 +1,376 @@
+import { CommonListItem } from '@toeverything/components/common';
+import { AddIcon } from '@toeverything/components/icons';
+import {
+ Input,
+ ListButton,
+ MuiClickAwayListener,
+ MuiGrow as Grow,
+ MuiPaper as Paper,
+ MuiPopper as Popper,
+ styled,
+} from '@toeverything/components/ui';
+import { services } from '@toeverything/datasource/db-service';
+import { HookType, PluginHooks, Virgo } from '@toeverything/framework/virgo';
+import React, {
+ ChangeEvent,
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from 'react';
+import { useParams } from 'react-router-dom';
+import { QueryBlocks, QueryResult } from '../../search';
+import { DoubleLinkMenuContainer } from './Container';
+
+const ADD_NEW_SUB_PAGE = 'AddNewSubPage';
+const ADD_NEW_PAGE = 'AddNewPage';
+const ARRAY_CODES = ['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown'];
+
+export type DoubleLinkMenuProps = {
+ editor: Virgo;
+ hooks: PluginHooks;
+ style?: { left: number; top: number };
+};
+
+type DoubleLinkMenuStyle = {
+ left: number;
+ top: number;
+ height: number;
+};
+
+export const DoubleLinkMenu = ({
+ editor,
+ hooks,
+ style,
+}: DoubleLinkMenuProps) => {
+ const { page_id: curPageId } = useParams();
+ const [isOpen, setIsOpen] = useState(false);
+ const [anchorEl, setAnchorEl] = useState(null);
+ const dialogRef = useRef();
+ const newPageSearchRef = useRef();
+ const [doubleLinkMenuStyle, setDoubleLinkMenuStyle] =
+ useState({
+ left: 0,
+ top: 0,
+ height: 0,
+ });
+
+ const [curBlockId, setCurBlockId] = useState();
+ const [searchText, setSearchText] = useState();
+ const [inAddNewPage, setInAddNewPage] = useState(false);
+ const [filterText, setFilterText] = useState('');
+ const [searchResultBlocks, setSearchResultBlocks] = useState(
+ []
+ );
+
+ const menuTypes = useMemo(() => {
+ return Object.values(searchResultBlocks)
+ .map(({ id }) => id)
+ .concat([ADD_NEW_SUB_PAGE, ADD_NEW_PAGE]);
+ }, [searchResultBlocks]);
+
+ const menuItems: CommonListItem[] = useMemo(() => {
+ const items: CommonListItem[] = [];
+ if (searchResultBlocks?.length > 0) {
+ items.push({
+ renderCustom: () => {
+ return (
+
+ );
+ },
+ });
+ items.push(
+ ...(searchResultBlocks?.map(
+ block =>
+ ({
+ block: {
+ ...block,
+ content: block.content || 'Untitled',
+ },
+ } as CommonListItem)
+ ) || [])
+ );
+ }
+
+ if (items.length > 0) {
+ items.push({ divider: 'newPage' });
+ }
+ items.push({
+ content: {
+ id: ADD_NEW_SUB_PAGE,
+ content: 'Add new sub-page',
+ icon: AddIcon,
+ },
+ });
+ !inAddNewPage &&
+ items.push({
+ content: {
+ id: ADD_NEW_PAGE,
+ content: 'Add new page in...',
+ icon: AddIcon,
+ },
+ });
+ return items;
+ }, [searchResultBlocks, inAddNewPage]);
+
+ useEffect(() => {
+ const text = inAddNewPage ? filterText : searchText;
+ QueryBlocks(editor, text, result => {
+ if (!inAddNewPage) {
+ result = result.filter(item => item.id !== curPageId);
+ }
+ setSearchResultBlocks(result);
+ });
+ }, [editor, searchText, filterText, inAddNewPage, curPageId]);
+
+ const hideMenu = useCallback(() => {
+ setIsOpen(false);
+ setInAddNewPage(false);
+ editor.blockHelper.removeDoubleLinkSearchSlash(curBlockId);
+ editor.scrollManager.unLock();
+ }, [curBlockId, editor]);
+
+ const resetState = useCallback(
+ (preNodeId: string, nextNodeId: string) => {
+ editor.blockHelper.removeDoubleLinkSearchSlash(preNodeId);
+ setCurBlockId(nextNodeId);
+ setSearchText('');
+ setIsOpen(true);
+ editor.scrollManager.lock();
+ const clientRect =
+ editor.selection.currentSelectInfo?.browserSelection
+ ?.getRangeAt(0)
+ ?.getBoundingClientRect();
+ if (clientRect) {
+ const rectTop = clientRect.top;
+ const { top, left } = editor.container.getBoundingClientRect();
+ setDoubleLinkMenuStyle({
+ top: rectTop - top,
+ left: clientRect.left - left,
+ height: clientRect.height,
+ });
+ setAnchorEl(dialogRef.current);
+ }
+ const textSelection = editor.blockHelper.selectionToSlateRange(
+ nextNodeId,
+ editor.selection.currentSelectInfo?.browserSelection
+ );
+ if (textSelection) {
+ const { anchor } = textSelection;
+ editor.blockHelper.setDoubleLinkSearchSlash(nextNodeId, anchor);
+ }
+ },
+ [editor]
+ );
+
+ const searchChange = useCallback(
+ async (event: React.KeyboardEvent) => {
+ if (ARRAY_CODES.includes(event.code)) {
+ return;
+ }
+ if (event.code === 'Backspace') {
+ const searchText =
+ editor.blockHelper.getDoubleLinkSearchSlashText(curBlockId);
+ if (!searchText || searchText === '[[') {
+ hideMenu();
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+ }
+ const { type, anchorNode } = editor.selection.currentSelectInfo;
+ if (
+ !isOpen ||
+ (type === 'Range' &&
+ anchorNode &&
+ anchorNode.id !== curBlockId &&
+ editor.blockHelper.isSelectionCollapsed(anchorNode.id))
+ ) {
+ const text = editor.blockHelper.getBlockTextBeforeSelection(
+ anchorNode.id
+ );
+ if (text.endsWith('[[')) {
+ resetState(curBlockId, anchorNode.id);
+ }
+ }
+ if (isOpen) {
+ const searchText =
+ editor.blockHelper.getDoubleLinkSearchSlashText(curBlockId);
+ if (searchText && searchText.startsWith('[[')) {
+ setSearchText(searchText.slice(2).trim());
+ }
+ }
+ },
+ [editor, isOpen, curBlockId, hideMenu]
+ );
+
+ const handleKeyup = useCallback(
+ (event: React.KeyboardEvent) => searchChange(event),
+ [searchChange]
+ );
+
+ const handleKeyDown = useCallback(
+ (event: React.KeyboardEvent) => {
+ if (!isOpen) {
+ return;
+ }
+ if (event.code === 'Escape') {
+ hideMenu();
+ }
+
+ if (event.code === 'Backspace') {
+ const searchText =
+ editor.blockHelper.getDoubleLinkSearchSlashText(curBlockId);
+ if (!searchText || searchText === '[[') {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+ }
+ },
+ [hideMenu, editor, isOpen, curBlockId]
+ );
+
+ useEffect(() => {
+ const sub = hooks
+ .get(HookType.ON_ROOT_NODE_KEYUP)
+ .subscribe(handleKeyup);
+ sub.add(
+ hooks
+ .get(HookType.ON_ROOT_NODE_KEYDOWN_CAPTURE)
+ .subscribe(handleKeyDown)
+ );
+
+ return () => {
+ sub.unsubscribe();
+ };
+ }, [handleKeyup, handleKeyDown, hooks]);
+
+ const insertDoubleLink = useCallback(
+ async (pageId: string) => {
+ editor.blockHelper.setSelectDoubleLinkSearchSlash(curBlockId);
+ await editor.blockHelper.insertDoubleLink(
+ editor.workspace,
+ pageId,
+ curBlockId
+ );
+ hideMenu();
+ },
+ [editor, curBlockId, hideMenu]
+ );
+
+ const addSubPage = useCallback(
+ async (parentPageId: string) => {
+ const newPage = await services.api.editorBlock.create({
+ workspace: editor.workspace,
+ type: 'page' as const,
+ });
+ services.api.editorBlock.update({
+ id: newPage.id,
+ workspace: editor.workspace,
+ properties: {
+ text: { value: [{ text: searchText }] },
+ },
+ });
+ await services.api.pageTree.addChildPageToWorkspace(
+ editor.workspace,
+ parentPageId,
+ newPage.id
+ );
+ return newPage.id;
+ },
+ [searchText, editor]
+ );
+
+ const handleSelected = async (id: string) => {
+ if (curBlockId) {
+ if (id === ADD_NEW_PAGE) {
+ setInAddNewPage(true);
+ setTimeout(() => {
+ newPageSearchRef.current?.focus();
+ });
+ return;
+ }
+ if (id === ADD_NEW_SUB_PAGE) {
+ const pageId = await addSubPage(curPageId);
+ insertDoubleLink(pageId);
+ return;
+ }
+ if (inAddNewPage) {
+ const pageId = await addSubPage(id);
+ insertDoubleLink(pageId);
+ } else {
+ insertDoubleLink(id);
+ }
+ }
+ };
+
+ const handleFilterChange = useCallback(
+ async (e: ChangeEvent) => {
+ const text = e.target.value;
+
+ await setFilterText(text);
+ },
+ []
+ );
+
+ return (
+
+ );
+};
+const NewPageSearchContainer = styled('div')({
+ padding: '8px 8px 0px 8px',
+});
diff --git a/libs/components/editor-plugins/src/menu/reference-menu/Plugin.tsx b/libs/components/editor-plugins/src/menu/double-link-menu/Plugin.tsx
similarity index 79%
rename from libs/components/editor-plugins/src/menu/reference-menu/Plugin.tsx
rename to libs/components/editor-plugins/src/menu/double-link-menu/Plugin.tsx
index 688adfd147..3933bf5f1c 100644
--- a/libs/components/editor-plugins/src/menu/reference-menu/Plugin.tsx
+++ b/libs/components/editor-plugins/src/menu/double-link-menu/Plugin.tsx
@@ -1,12 +1,11 @@
import { StrictMode } from 'react';
-
import { BasePlugin } from '../../base-plugin';
import { PluginRenderRoot } from '../../utils';
-import { ReferenceMenu } from './ReferenceMenu';
+import { DoubleLinkMenu } from './DoubleLinkMenu';
const PLUGIN_NAME = 'reference-menu';
-export class ReferenceMenuPlugin extends BasePlugin {
+export class DoubleLinkMenuPlugin extends BasePlugin {
private _root?: PluginRenderRoot;
public static override get pluginName(): string {
@@ -22,7 +21,7 @@ export class ReferenceMenuPlugin extends BasePlugin {
this._root?.render(
-
+
);
}
diff --git a/libs/components/editor-plugins/src/menu/double-link-menu/index.ts b/libs/components/editor-plugins/src/menu/double-link-menu/index.ts
new file mode 100644
index 0000000000..e287e74e03
--- /dev/null
+++ b/libs/components/editor-plugins/src/menu/double-link-menu/index.ts
@@ -0,0 +1 @@
+export { DoubleLinkMenuPlugin } from './Plugin';
diff --git a/libs/components/editor-plugins/src/menu/group-menu/GropuMenu.tsx b/libs/components/editor-plugins/src/menu/group-menu/GropuMenu.tsx
index 781c2c3a25..8ccf8b5e55 100644
--- a/libs/components/editor-plugins/src/menu/group-menu/GropuMenu.tsx
+++ b/libs/components/editor-plugins/src/menu/group-menu/GropuMenu.tsx
@@ -75,21 +75,6 @@ export const GroupMenu = function ({ editor, hooks }: GroupMenuProps) {
[editor, groupBlock]
);
- const handleRootDrop = useCallback(
- async (e: React.DragEvent) => {
- let groupBlockOnDrop = null;
- if (editor.dragDropManager.isDragGroup(e)) {
- groupBlockOnDrop = await editor.getGroupBlockByPoint(
- new Point(e.clientX, e.clientY)
- );
- if (groupBlockOnDrop?.id === groupBlock?.id) {
- groupBlockOnDrop = null;
- }
- }
- },
- [editor, groupBlock]
- );
-
const handleRootMouseLeave = useCallback(() => setGroupBlock(null), []);
const handleRootDragEnd = () => {
@@ -128,7 +113,6 @@ export const GroupMenu = function ({ editor, hooks }: GroupMenuProps) {
handleRootMouseMove,
handleRootMouseDown,
handleRootDragOver,
- handleRootDrop,
handleRootMouseLeave,
]);
@@ -170,7 +154,11 @@ export const GroupMenu = function ({ editor, hooks }: GroupMenuProps) {
setShowMenu(false);
if (groupBlock) {
- const unobserve = groupBlock.onUpdate(() => setGroupBlock(null));
+ const unobserve = groupBlock.onUpdate(() => {
+ requestAnimationFrame(() => {
+ setGroupBlock(null);
+ });
+ });
return unobserve;
}
return undefined;
diff --git a/libs/components/editor-plugins/src/menu/group-menu/Plugin.tsx b/libs/components/editor-plugins/src/menu/group-menu/Plugin.tsx
index 115e754202..6d4561d667 100644
--- a/libs/components/editor-plugins/src/menu/group-menu/Plugin.tsx
+++ b/libs/components/editor-plugins/src/menu/group-menu/Plugin.tsx
@@ -14,7 +14,7 @@ export class GroupMenuPlugin extends BasePlugin {
}
protected override _onRender(): void {
- if (this.editor.isWhiteboard) return;
+ if (this.editor.isEdgeless) return;
this.root = new PluginRenderRoot({
name: PLUGIN_NAME,
render: this.editor.reactRenderRoot.render,
diff --git a/libs/components/editor-plugins/src/menu/index.ts b/libs/components/editor-plugins/src/menu/index.ts
index 50d4133651..190e3a5109 100644
--- a/libs/components/editor-plugins/src/menu/index.ts
+++ b/libs/components/editor-plugins/src/menu/index.ts
@@ -1,9 +1,7 @@
+export { CommandMenuPlugin } from './command-menu';
+export { DoubleLinkMenuPlugin } from './double-link-menu';
+export { GroupMenuPlugin } from './group-menu';
export { InlineMenuPlugin } from './inline-menu';
export { LeftMenuPlugin } from './left-menu/LeftMenuPlugin';
-export { CommandMenuPlugin } from './command-menu';
-export { ReferenceMenuPlugin } from './reference-menu';
-export { SelectionGroupPlugin } from './selection-group-menu';
-
export { MENU_WIDTH as menuWidth } from './left-menu/menu-config';
-
-export { GroupMenuPlugin } from './group-menu';
+export { SelectionGroupPlugin } from './selection-group-menu';
diff --git a/libs/components/editor-plugins/src/menu/inline-menu/utils.ts b/libs/components/editor-plugins/src/menu/inline-menu/utils.ts
index 14d2d68374..78f03fbcf9 100644
--- a/libs/components/editor-plugins/src/menu/inline-menu/utils.ts
+++ b/libs/components/editor-plugins/src/menu/inline-menu/utils.ts
@@ -1,47 +1,47 @@
/* eslint-disable max-lines */
-import {
- HeadingOneIcon,
- HeadingTwoIcon,
- HeadingThreeIcon,
- ToDoIcon,
- NumberIcon,
- BulletIcon,
- FormatBoldEmphasisIcon,
- FormatItalicIcon,
- FormatStrikethroughIcon,
- LinkIcon,
- CodeIcon,
- FormatColorTextIcon,
- FormatBackgroundIcon,
- AlignLeftIcon,
- AlignCenterIcon,
- AlignRightIcon,
- TurnIntoIcon,
- BacklinksIcon,
- MoreIcon,
- TextFontIcon,
- QuoteIcon,
- CalloutIcon,
- FileIcon,
- ImageIcon,
- PagesIcon,
- CodeBlockIcon,
- CommentIcon,
-} from '@toeverything/components/icons';
import {
fontBgColorPalette,
fontColorPalette,
type TextAlignOptions,
} from '@toeverything/components/common';
-import { Virgo } from '@toeverything/framework/virgo';
-import { BlockFlavorKeys, Protocol } from '@toeverything/datasource/db-service';
-import { ClickItemHandler, InlineMenuItem } from './types';
import {
- inlineMenuNamesKeys,
- inlineMenuNamesForFontColor,
- INLINE_MENU_UI_TYPES,
+ BacklinksIcon,
+ BulletIcon,
+ CalloutIcon,
+ CodeBlockIcon,
+ CodeIcon,
+ CommentIcon,
+ FileIcon,
+ FormatBackgroundIcon,
+ FormatBoldEmphasisIcon,
+ FormatColorTextIcon,
+ FormatItalicIcon,
+ FormatStrikethroughIcon,
+ HeadingOneIcon,
+ HeadingThreeIcon,
+ HeadingTwoIcon,
+ ImageIcon,
+ LinkIcon,
+ MoreIcon,
+ NumberIcon,
+ PagesIcon,
+ QuoteIcon,
+ TextAlignCenterIcon,
+ TextAlignLeftIcon,
+ TextAlignRightIcon,
+ TextFontIcon,
+ ToDoIcon,
+ TurnIntoIcon,
+} from '@toeverything/components/icons';
+import { BlockFlavorKeys, Protocol } from '@toeverything/datasource/db-service';
+import { Virgo } from '@toeverything/framework/virgo';
+import {
inlineMenuNames,
+ inlineMenuNamesForFontColor,
+ inlineMenuNamesKeys,
+ INLINE_MENU_UI_TYPES,
} from './config';
+import { ClickItemHandler, InlineMenuItem } from './types';
const convert_to_block_type = async ({
editor,
@@ -732,27 +732,27 @@ export const getInlineMenuData = ({
},
{
type: INLINE_MENU_UI_TYPES.dropdown,
- icon: AlignLeftIcon,
+ icon: TextAlignLeftIcon,
name: inlineMenuNames.currentTextAlign,
nameKey: inlineMenuNamesKeys.currentTextAlign,
children: [
{
type: INLINE_MENU_UI_TYPES.icon,
- icon: AlignLeftIcon,
+ icon: TextAlignLeftIcon,
name: inlineMenuNames.alignLeft,
nameKey: inlineMenuNamesKeys.alignLeft,
onClick: common_handler_for_inline_menu,
},
{
type: INLINE_MENU_UI_TYPES.icon,
- icon: AlignCenterIcon,
+ icon: TextAlignCenterIcon,
name: inlineMenuNames.alignCenter,
nameKey: inlineMenuNamesKeys.alignCenter,
onClick: common_handler_for_inline_menu,
},
{
type: INLINE_MENU_UI_TYPES.icon,
- icon: AlignRightIcon,
+ icon: TextAlignRightIcon,
name: inlineMenuNames.alignRight,
nameKey: inlineMenuNamesKeys.alignRight,
onClick: common_handler_for_inline_menu,
diff --git a/libs/components/editor-plugins/src/menu/left-menu/LeftMenu.tsx b/libs/components/editor-plugins/src/menu/left-menu/LeftMenu.tsx
index 38db125aca..043b9a77c6 100644
--- a/libs/components/editor-plugins/src/menu/left-menu/LeftMenu.tsx
+++ b/libs/components/editor-plugins/src/menu/left-menu/LeftMenu.tsx
@@ -1,8 +1,10 @@
import { useMemo } from 'react';
import { Virgo, PluginHooks } from '@toeverything/framework/virgo';
import { Cascader, CascaderItemProps } from '@toeverything/components/ui';
+import { Protocol } from '@toeverything/datasource/db-service';
import { TurnIntoMenu } from './TurnIntoMenu';
import {
+ AddViewIcon,
DeleteCashBinIcon,
TurnIntoIcon,
UngroupIcon,
@@ -45,6 +47,24 @@ export function LeftMenu(props: LeftMenuProps) {
),
icon: ,
},
+ {
+ title: 'Add A Below Block',
+ icon: ,
+ callback: async () => {
+ const block = await editor.getBlockById(blockId);
+ const belowType = [
+ Protocol.Block.Type.numbered,
+ Protocol.Block.Type.bullet,
+ Protocol.Block.Type.todo,
+ ].some(type => type === block.type)
+ ? block.type
+ : Protocol.Block.Type.text;
+ editor.commands.blockCommands.createNextBlock(
+ blockId,
+ belowType
+ );
+ },
+ },
{
title: 'Divide Here As A New Group',
icon: ,
diff --git a/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx b/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx
index 3b432167ee..9c339e8630 100644
--- a/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx
+++ b/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx
@@ -1,15 +1,15 @@
-import { HookType, BlockDropPlacement } from '@toeverything/framework/virgo';
-import { StrictMode } from 'react';
-import { BasePlugin } from '../../base-plugin';
-import { ignoreBlockTypes } from './menu-config';
-import {
- LineInfoSubject,
- LeftMenuDraggable,
- BlockDomInfo,
-} from './LeftMenuDraggable';
-import { PluginRenderRoot } from '../../utils';
-import { Subject, throttleTime } from 'rxjs';
+import { BlockDropPlacement, HookType } from '@toeverything/framework/virgo';
import { domToRect, last, Point } from '@toeverything/utils';
+import { StrictMode } from 'react';
+import { Subject, throttleTime } from 'rxjs';
+import { BasePlugin } from '../../base-plugin';
+import { PluginRenderRoot } from '../../utils';
+import {
+ BlockDomInfo,
+ LeftMenuDraggable,
+ LineInfoSubject,
+} from './LeftMenuDraggable';
+import { ignoreBlockTypes } from './menu-config';
const DRAG_THROTTLE_DELAY = 60;
export class LeftMenuPlugin extends BasePlugin {
private _mousedown?: boolean;
@@ -111,6 +111,10 @@ export class LeftMenuPlugin extends BasePlugin {
block.dom,
block.id
);
+ if (!targetBlock.dom) {
+ console.warn('Can not find dom bind with block', targetBlock);
+ return;
+ }
this._lineInfo.next({
direction,
blockInfo: {
diff --git a/libs/components/editor-plugins/src/menu/reference-menu/Container.tsx b/libs/components/editor-plugins/src/menu/reference-menu/Container.tsx
deleted file mode 100644
index 42ca2d679d..0000000000
--- a/libs/components/editor-plugins/src/menu/reference-menu/Container.tsx
+++ /dev/null
@@ -1,190 +0,0 @@
-import React, { useEffect, useState, useCallback, useRef } from 'react';
-
-import { Virgo, PluginHooks, HookType } from '@toeverything/framework/virgo';
-import {
- CommonList,
- CommonListItem,
- commonListContainer,
-} from '@toeverything/components/common';
-import { domToRect } from '@toeverything/utils';
-import { styled } from '@toeverything/components/ui';
-
-import { QueryResult } from '../../search';
-
-export type ReferenceMenuContainerProps = {
- editor: Virgo;
- hooks: PluginHooks;
- style?: React.CSSProperties;
- isShow?: boolean;
- blockId: string;
- onSelected?: (item: string) => void;
- onClose?: () => void;
- searchBlocks?: QueryResult;
- types?: Array;
-};
-
-export const ReferenceMenuContainer = ({
- hooks,
- isShow = false,
- onSelected,
- onClose,
- types,
- searchBlocks,
- style,
-}: ReferenceMenuContainerProps) => {
- const menu_ref = useRef(null);
- const [current_item, set_current_item] = useState();
- const [need_check_into_view, set_need_check_into_view] =
- useState(false);
-
- useEffect(() => {
- if (need_check_into_view) {
- if (current_item && menu_ref.current) {
- const item_ele =
- menu_ref.current.querySelector(
- `.item-${current_item}`
- );
- const scroll_ele =
- menu_ref.current.querySelector(
- `.${commonListContainer}`
- );
- if (item_ele) {
- const itemRect = domToRect(item_ele);
- const scrollRect = domToRect(scroll_ele);
- if (
- itemRect.top < scrollRect.top ||
- itemRect.bottom > scrollRect.bottom
- ) {
- // IMP: may be do it with self function
- item_ele.scrollIntoView({
- block: 'nearest',
- });
- }
- }
- }
- set_need_check_into_view(false);
- }
- }, [need_check_into_view, current_item]);
-
- useEffect(() => {
- if (isShow && types && !current_item) set_current_item(types[0]);
- if (!isShow) onClose?.();
- }, [current_item, isShow, onClose, types]);
-
- useEffect(() => {
- if (isShow && types) {
- if (!types.includes(current_item)) {
- set_need_check_into_view(true);
- if (types.length) {
- set_current_item(types[0]);
- } else {
- set_current_item(undefined);
- }
- }
- }
- }, [isShow, types, current_item]);
-
- const handle_click_up = useCallback(
- (event: React.KeyboardEvent) => {
- if (isShow && types && event.code === 'ArrowUp') {
- event.preventDefault();
- if (!current_item && types.length) {
- set_current_item(types[types.length - 1]);
- }
- if (current_item) {
- const idx = types.indexOf(current_item);
- if (idx > 0) {
- set_need_check_into_view(true);
- set_current_item(types[idx - 1]);
- }
- }
- }
- },
- [isShow, types, current_item]
- );
-
- const handle_click_down = useCallback(
- (event: React.KeyboardEvent) => {
- if (isShow && types && event.code === 'ArrowDown') {
- event.preventDefault();
- if (!current_item && types.length) {
- set_current_item(types[0]);
- }
- if (current_item) {
- const idx = types.indexOf(current_item);
- if (idx < types.length - 1) {
- set_need_check_into_view(true);
- set_current_item(types[idx + 1]);
- }
- }
- }
- },
- [isShow, types, current_item]
- );
-
- const handle_click_enter = useCallback(
- async (event: React.KeyboardEvent) => {
- if (isShow && event.code === 'Enter' && current_item) {
- event.preventDefault();
- onSelected && onSelected(current_item);
- }
- },
- [isShow, current_item, onSelected]
- );
-
- const handle_key_down = useCallback(
- (event: React.KeyboardEvent) => {
- handle_click_up(event);
- handle_click_down(event);
- handle_click_enter(event);
- },
- [handle_click_up, handle_click_down, handle_click_enter]
- );
-
- useEffect(() => {
- const sub = hooks
- .get(HookType.ON_ROOT_NODE_KEYDOWN_CAPTURE)
- .subscribe(handle_key_down);
-
- return () => {
- sub.unsubscribe();
- };
- }, [hooks, handle_key_down]);
-
- return isShow ? (
-
-
- ({ block } as CommonListItem)
- ) || []
- }
- onSelected={type => onSelected?.(type)}
- currentItem={current_item}
- setCurrentItem={set_current_item}
- />
-
-
- ) : null;
-};
-
-const RootContainer = styled('div')(({ theme }) => ({
- position: 'fixed',
- zIndex: 1,
- maxHeight: '525px',
- borderRadius: '10px',
- boxShadow: theme.affine.shadows.shadow1,
- backgroundColor: '#fff',
- padding: '8px 4px',
-}));
-
-const ContentContainer = styled('div')(({ theme }) => ({
- display: 'flex',
- overflow: 'hidden',
- maxHeight: '493px',
-}));
diff --git a/libs/components/editor-plugins/src/menu/reference-menu/ReferenceMenu.tsx b/libs/components/editor-plugins/src/menu/reference-menu/ReferenceMenu.tsx
deleted file mode 100644
index af1cd96cea..0000000000
--- a/libs/components/editor-plugins/src/menu/reference-menu/ReferenceMenu.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from 'react';
-
-import { MuiClickAwayListener, styled } from '@toeverything/components/ui';
-import { Virgo, HookType, PluginHooks } from '@toeverything/framework/virgo';
-import { Point } from '@toeverything/utils';
-
-import { ReferenceMenuContainer } from './Container';
-import { QueryBlocks, QueryResult } from '../../search';
-
-export type ReferenceMenuProps = {
- editor: Virgo;
- hooks: PluginHooks;
- style?: { left: number; top: number };
-};
-
-export type RefLinkComponent = {
- type: 'reflink';
- reference: string;
-};
-
-const BEFORE_REGEX = /\[\[(.*)$/;
-
-export const ReferenceMenu = ({ editor, hooks, style }: ReferenceMenuProps) => {
- const [is_show, set_is_show] = useState(false);
- const [block_id, set_block_id] = useState();
- const [position, set_position] = useState(new Point(0, 0));
-
- const [search_text, set_search_text] = useState('');
- const [search_blocks, set_search_blocks] = useState([]);
-
- useEffect(() => {
- QueryBlocks(editor, search_text, result => set_search_blocks(result));
- }, [editor, search_text]);
-
- const search_block_ids = useMemo(
- () => Object.values(search_blocks).map(({ id }) => id),
- [search_blocks]
- );
-
- const handle_search = useCallback(
- async (event: React.KeyboardEvent) => {
- const { type, anchorNode } = editor.selection.currentSelectInfo;
- if (
- type === 'Range' &&
- anchorNode &&
- editor.blockHelper.isSelectionCollapsed(anchorNode.id)
- ) {
- const text = editor.blockHelper.getBlockTextBeforeSelection(
- anchorNode.id
- );
- const matched = BEFORE_REGEX.exec(text)?.[1];
-
- if (typeof matched === 'string') {
- if (event.key === '[') set_is_show(true);
-
- set_block_id(anchorNode.id);
- set_search_text(matched);
-
- const rect =
- editor.selection.currentSelectInfo?.browserSelection
- ?.getRangeAt(0)
- ?.getBoundingClientRect();
- if (rect) {
- set_position(new Point(rect.left, rect.top + 24));
- }
- } else if (is_show) {
- set_is_show(false);
- }
- }
- },
- [editor, is_show]
- );
-
- const handle_keyup = useCallback(
- (event: React.KeyboardEvent) => handle_search(event),
- [handle_search]
- );
-
- const handle_key_down = useCallback(
- (event: React.KeyboardEvent) => {
- if (event.code === 'Escape') {
- set_is_show(false);
- }
- },
- []
- );
-
- useEffect(() => {
- const sub = hooks
- .get(HookType.ON_ROOT_NODE_KEYUP)
- .subscribe(handle_keyup);
- sub.add(
- hooks
- .get(HookType.ON_ROOT_NODE_KEYDOWN_CAPTURE)
- .subscribe(handle_key_down)
- );
-
- return () => {
- sub.unsubscribe();
- };
- }, [handle_keyup, handle_key_down, hooks]);
-
- const handle_selected = async (reference: string) => {
- if (block_id) {
- const { anchorNode } = editor.selection.currentSelectInfo;
- editor.blockHelper.insertReference(
- reference,
- anchorNode.id,
- editor.selection.currentSelectInfo?.browserSelection,
- -search_text.length - 2
- );
- }
-
- set_is_show(false);
- };
-
- const handle_close = () => {
- block_id && editor.blockHelper.removeSearchSlash(block_id);
- };
-
- return (
-
- set_is_show(false)}>
-
-
-
-
-
- );
-};
-
-const ReferenceMenuWrapper = styled('div')({
- position: 'absolute',
- zIndex: 1,
-});
diff --git a/libs/components/editor-plugins/src/menu/reference-menu/index.ts b/libs/components/editor-plugins/src/menu/reference-menu/index.ts
deleted file mode 100644
index 0a3879e398..0000000000
--- a/libs/components/editor-plugins/src/menu/reference-menu/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { ReferenceMenuPlugin } from './Plugin';
diff --git a/libs/components/editor-plugins/src/search/Search.tsx b/libs/components/editor-plugins/src/search/Search.tsx
index 6b02b6334e..b689345f64 100644
--- a/libs/components/editor-plugins/src/search/Search.tsx
+++ b/libs/components/editor-plugins/src/search/Search.tsx
@@ -1,16 +1,15 @@
-import { useCallback, useEffect, useState } from 'react';
-import { useNavigate, useParams } from 'react-router';
-import style9 from 'style9';
-
import { BlockPreview } from '@toeverything/components/common';
import {
- TransitionsModal,
MuiBox as Box,
MuiBox,
styled,
+ TransitionsModal,
} from '@toeverything/components/ui';
-import { Virgo, BlockEditor } from '@toeverything/framework/virgo';
+import { BlockEditor, Virgo } from '@toeverything/framework/virgo';
import { throttle } from '@toeverything/utils';
+import { useCallback, useEffect, useState } from 'react';
+import { useNavigate, useParams } from 'react-router';
+import style9 from 'style9';
const styles = style9.create({
wrapper: {
@@ -37,9 +36,7 @@ const query_blocks = (
search: string,
callback: (result: QueryResult) => void
) => {
- (editor as BlockEditor)
- .search(search)
- .then(pages => callback(pages.filter(b => !!b.content)));
+ (editor as BlockEditor).search(search).then(pages => callback(pages));
};
export const QueryBlocks = throttle(query_blocks, 500);
diff --git a/libs/components/editor-plugins/src/search/index.tsx b/libs/components/editor-plugins/src/search/index.tsx
index f49de00a70..41a13695c4 100644
--- a/libs/components/editor-plugins/src/search/index.tsx
+++ b/libs/components/editor-plugins/src/search/index.tsx
@@ -1,11 +1,10 @@
-/* eslint-disable filename-rules/match */
import { StrictMode } from 'react';
import { HookType } from '@toeverything/framework/virgo';
import { BasePlugin } from '../base-plugin';
-import { Search } from './Search';
import { PluginRenderRoot } from '../utils';
+import { Search } from './Search';
export class FullTextSearchPlugin extends BasePlugin {
#root?: PluginRenderRoot;
@@ -58,5 +57,5 @@ export class FullTextSearchPlugin extends BasePlugin {
}
}
-export type { QueryResult } from './Search';
export { QueryBlocks } from './Search';
+export type { QueryResult } from './Search';
diff --git a/libs/components/icons/src/auto-icons/align/align.svg b/libs/components/icons/src/auto-icons/align/align.svg
new file mode 100644
index 0000000000..7925bf7844
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/align/align.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/align/align.tsx b/libs/components/icons/src/auto-icons/align/align.tsx
new file mode 100644
index 0000000000..61997d17f6
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/align/align.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface AlignIconProps extends Omit {
+ color?: string
+}
+
+export const AlignIcon = ({ color, style, ...props}: AlignIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/bring-forward/bring-forward.svg b/libs/components/icons/src/auto-icons/bring-forward/bring-forward.svg
new file mode 100644
index 0000000000..638f6aa740
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/bring-forward/bring-forward.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/bring-forward/bring-forward.tsx b/libs/components/icons/src/auto-icons/bring-forward/bring-forward.tsx
new file mode 100644
index 0000000000..067253a85e
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/bring-forward/bring-forward.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface BringForwardIconProps extends Omit {
+ color?: string
+}
+
+export const BringForwardIcon = ({ color, style, ...props}: BringForwardIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/bring-to-front/bring-to-front.svg b/libs/components/icons/src/auto-icons/bring-to-front/bring-to-front.svg
new file mode 100644
index 0000000000..7158fe6f56
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/bring-to-front/bring-to-front.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/bring-to-front/bring-to-front.tsx b/libs/components/icons/src/auto-icons/bring-to-front/bring-to-front.tsx
new file mode 100644
index 0000000000..9424307345
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/bring-to-front/bring-to-front.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface BringToFrontIconProps extends Omit {
+ color?: string
+}
+
+export const BringToFrontIcon = ({ color, style, ...props}: BringToFrontIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/index.ts b/libs/components/icons/src/auto-icons/index.ts
index 8ea2f6c0a0..bf29051323 100644
--- a/libs/components/icons/src/auto-icons/index.ts
+++ b/libs/components/icons/src/auto-icons/index.ts
@@ -1,4 +1,4 @@
-export const timestamp = 1660270988401;
+export const timestamp = 1660793621971;
export * from './image/image';
export * from './format-clear/format-clear';
export * from './backward-undo/backward-undo';
@@ -26,10 +26,10 @@ export * from './format-italic/format-italic';
export * from './format-strikethrough/format-strikethrough';
export * from './format-color-text/format-color-text';
export * from './format-background/format-background';
-export * from './align-left/align-left';
-export * from './align-center/align-center';
-export * from './align-right/align-right';
-export * from './align-justify/align-justify';
+export * from './text-align-left/text-align-left';
+export * from './text-align-center/text-align-center';
+export * from './text-align-right/text-align-right';
+export * from './text-align-justify/text-align-justify';
export * from './arrow-drop-down/arrow-drop-down';
export * from './arrow-right/arrow-right';
export * from './more/more';
@@ -129,4 +129,18 @@ export * from './unlock/unlock';
export * from './more-tags-an-subblocks/more-tags-an-subblocks';
export * from './page-in-page-tree/page-in-page-tree';
export * from './pin/pin';
-export * from './add/add';
\ No newline at end of file
+export * from './add/add';
+export * from './shapes-align-left/shapes-align-left';
+export * from './shapes-align-right/shapes-align-right';
+export * from './shapes-distribute-horizontal/shapes-distribute-horizontal';
+export * from './shapes-distribute-vertical/shapes-distribute-vertical';
+export * from './shapes-align-top/shapes-align-top';
+export * from './shapes-align-bottom/shapes-align-bottom';
+export * from './shapes-align-horizontal-center/shapes-align-horizontal-center';
+export * from './shapes-align-vertical-center/shapes-align-vertical-center';
+export * from './bring-forward/bring-forward';
+export * from './send-backward/send-backward';
+export * from './bring-to-front/bring-to-front';
+export * from './send-to-back/send-to-back';
+export * from './align/align';
+export * from './layers/layers';
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/layers/layers.svg b/libs/components/icons/src/auto-icons/layers/layers.svg
new file mode 100644
index 0000000000..9859478a12
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/layers/layers.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/layers/layers.tsx b/libs/components/icons/src/auto-icons/layers/layers.tsx
new file mode 100644
index 0000000000..be23ad2287
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/layers/layers.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface LayersIconProps extends Omit {
+ color?: string
+}
+
+export const LayersIcon = ({ color, style, ...props}: LayersIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/send-backward/send-backward.svg b/libs/components/icons/src/auto-icons/send-backward/send-backward.svg
new file mode 100644
index 0000000000..75d31da632
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/send-backward/send-backward.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/send-backward/send-backward.tsx b/libs/components/icons/src/auto-icons/send-backward/send-backward.tsx
new file mode 100644
index 0000000000..41cd3ac134
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/send-backward/send-backward.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface SendBackwardIconProps extends Omit {
+ color?: string
+}
+
+export const SendBackwardIcon = ({ color, style, ...props}: SendBackwardIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/send-to-back/send-to-back.svg b/libs/components/icons/src/auto-icons/send-to-back/send-to-back.svg
new file mode 100644
index 0000000000..a114dfdd62
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/send-to-back/send-to-back.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/send-to-back/send-to-back.tsx b/libs/components/icons/src/auto-icons/send-to-back/send-to-back.tsx
new file mode 100644
index 0000000000..479a092f28
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/send-to-back/send-to-back.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface SendToBackIconProps extends Omit {
+ color?: string
+}
+
+export const SendToBackIcon = ({ color, style, ...props}: SendToBackIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-align-bottom/shapes-align-bottom.svg b/libs/components/icons/src/auto-icons/shapes-align-bottom/shapes-align-bottom.svg
new file mode 100644
index 0000000000..2518cc3925
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-bottom/shapes-align-bottom.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-align-bottom/shapes-align-bottom.tsx b/libs/components/icons/src/auto-icons/shapes-align-bottom/shapes-align-bottom.tsx
new file mode 100644
index 0000000000..fdb321f59b
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-bottom/shapes-align-bottom.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesAlignBottomIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesAlignBottomIcon = ({ color, style, ...props}: ShapesAlignBottomIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-align-horizontal-center/shapes-align-horizontal-center.svg b/libs/components/icons/src/auto-icons/shapes-align-horizontal-center/shapes-align-horizontal-center.svg
new file mode 100644
index 0000000000..946c34d529
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-horizontal-center/shapes-align-horizontal-center.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-align-horizontal-center/shapes-align-horizontal-center.tsx b/libs/components/icons/src/auto-icons/shapes-align-horizontal-center/shapes-align-horizontal-center.tsx
new file mode 100644
index 0000000000..76f714faaa
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-horizontal-center/shapes-align-horizontal-center.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesAlignHorizontalCenterIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesAlignHorizontalCenterIcon = ({ color, style, ...props}: ShapesAlignHorizontalCenterIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-align-left/shapes-align-left.svg b/libs/components/icons/src/auto-icons/shapes-align-left/shapes-align-left.svg
new file mode 100644
index 0000000000..81c33baf33
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-left/shapes-align-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-align-left/shapes-align-left.tsx b/libs/components/icons/src/auto-icons/shapes-align-left/shapes-align-left.tsx
new file mode 100644
index 0000000000..807b0c91e7
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-left/shapes-align-left.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesAlignLeftIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesAlignLeftIcon = ({ color, style, ...props}: ShapesAlignLeftIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-align-right/shapes-align-right.svg b/libs/components/icons/src/auto-icons/shapes-align-right/shapes-align-right.svg
new file mode 100644
index 0000000000..ed84addfab
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-right/shapes-align-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-align-right/shapes-align-right.tsx b/libs/components/icons/src/auto-icons/shapes-align-right/shapes-align-right.tsx
new file mode 100644
index 0000000000..ae3f04466d
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-right/shapes-align-right.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesAlignRightIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesAlignRightIcon = ({ color, style, ...props}: ShapesAlignRightIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-align-top/shapes-align-top.svg b/libs/components/icons/src/auto-icons/shapes-align-top/shapes-align-top.svg
new file mode 100644
index 0000000000..e688501fbf
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-top/shapes-align-top.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-align-top/shapes-align-top.tsx b/libs/components/icons/src/auto-icons/shapes-align-top/shapes-align-top.tsx
new file mode 100644
index 0000000000..b1ab7c9616
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-top/shapes-align-top.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesAlignTopIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesAlignTopIcon = ({ color, style, ...props}: ShapesAlignTopIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-align-vertical-center/shapes-align-vertical-center.svg b/libs/components/icons/src/auto-icons/shapes-align-vertical-center/shapes-align-vertical-center.svg
new file mode 100644
index 0000000000..a58d6ed611
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-vertical-center/shapes-align-vertical-center.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-align-vertical-center/shapes-align-vertical-center.tsx b/libs/components/icons/src/auto-icons/shapes-align-vertical-center/shapes-align-vertical-center.tsx
new file mode 100644
index 0000000000..90101ff662
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-align-vertical-center/shapes-align-vertical-center.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesAlignVerticalCenterIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesAlignVerticalCenterIcon = ({ color, style, ...props}: ShapesAlignVerticalCenterIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-distribute-horizontal/shapes-distribute-horizontal.svg b/libs/components/icons/src/auto-icons/shapes-distribute-horizontal/shapes-distribute-horizontal.svg
new file mode 100644
index 0000000000..78934c6d1a
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-distribute-horizontal/shapes-distribute-horizontal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-distribute-horizontal/shapes-distribute-horizontal.tsx b/libs/components/icons/src/auto-icons/shapes-distribute-horizontal/shapes-distribute-horizontal.tsx
new file mode 100644
index 0000000000..e2ac83cbc5
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-distribute-horizontal/shapes-distribute-horizontal.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesDistributeHorizontalIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesDistributeHorizontalIcon = ({ color, style, ...props}: ShapesDistributeHorizontalIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/shapes-distribute-vertical/shapes-distribute-vertical.svg b/libs/components/icons/src/auto-icons/shapes-distribute-vertical/shapes-distribute-vertical.svg
new file mode 100644
index 0000000000..b3189fda48
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-distribute-vertical/shapes-distribute-vertical.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/libs/components/icons/src/auto-icons/shapes-distribute-vertical/shapes-distribute-vertical.tsx b/libs/components/icons/src/auto-icons/shapes-distribute-vertical/shapes-distribute-vertical.tsx
new file mode 100644
index 0000000000..0d581d4bdd
--- /dev/null
+++ b/libs/components/icons/src/auto-icons/shapes-distribute-vertical/shapes-distribute-vertical.tsx
@@ -0,0 +1,18 @@
+
+// eslint-disable-next-line no-restricted-imports
+import { SvgIcon, SvgIconProps } from '@mui/material';
+
+export interface ShapesDistributeVerticalIconProps extends Omit {
+ color?: string
+}
+
+export const ShapesDistributeVerticalIcon = ({ color, style, ...props}: ShapesDistributeVerticalIconProps) => {
+ const propsStyles = {"color": color};
+ const customStyles = {};
+ const styles = {...propsStyles, ...customStyles, ...style}
+ return (
+
+
+
+ )
+};
diff --git a/libs/components/icons/src/auto-icons/align-center/align-center.svg b/libs/components/icons/src/auto-icons/text-align-center/text-align-center.svg
similarity index 100%
rename from libs/components/icons/src/auto-icons/align-center/align-center.svg
rename to libs/components/icons/src/auto-icons/text-align-center/text-align-center.svg
diff --git a/libs/components/icons/src/auto-icons/align-center/align-center.tsx b/libs/components/icons/src/auto-icons/text-align-center/text-align-center.tsx
similarity index 73%
rename from libs/components/icons/src/auto-icons/align-center/align-center.tsx
rename to libs/components/icons/src/auto-icons/text-align-center/text-align-center.tsx
index 71bcaac6e2..0586b2efb9 100644
--- a/libs/components/icons/src/auto-icons/align-center/align-center.tsx
+++ b/libs/components/icons/src/auto-icons/text-align-center/text-align-center.tsx
@@ -2,11 +2,11 @@
// eslint-disable-next-line no-restricted-imports
import { SvgIcon, SvgIconProps } from '@mui/material';
-export interface AlignCenterIconProps extends Omit {
+export interface TextAlignCenterIconProps extends Omit {
color?: string
}
-export const AlignCenterIcon = ({ color, style, ...props}: AlignCenterIconProps) => {
+export const TextAlignCenterIcon = ({ color, style, ...props}: TextAlignCenterIconProps) => {
const propsStyles = {"color": color};
const customStyles = {};
const styles = {...propsStyles, ...customStyles, ...style}
diff --git a/libs/components/icons/src/auto-icons/align-justify/align-justify.svg b/libs/components/icons/src/auto-icons/text-align-justify/text-align-justify.svg
similarity index 100%
rename from libs/components/icons/src/auto-icons/align-justify/align-justify.svg
rename to libs/components/icons/src/auto-icons/text-align-justify/text-align-justify.svg
diff --git a/libs/components/icons/src/auto-icons/align-justify/align-justify.tsx b/libs/components/icons/src/auto-icons/text-align-justify/text-align-justify.tsx
similarity index 73%
rename from libs/components/icons/src/auto-icons/align-justify/align-justify.tsx
rename to libs/components/icons/src/auto-icons/text-align-justify/text-align-justify.tsx
index 86dfcc43e8..943d2c7fa6 100644
--- a/libs/components/icons/src/auto-icons/align-justify/align-justify.tsx
+++ b/libs/components/icons/src/auto-icons/text-align-justify/text-align-justify.tsx
@@ -2,11 +2,11 @@
// eslint-disable-next-line no-restricted-imports
import { SvgIcon, SvgIconProps } from '@mui/material';
-export interface AlignJustifyIconProps extends Omit {
+export interface TextAlignJustifyIconProps extends Omit {
color?: string
}
-export const AlignJustifyIcon = ({ color, style, ...props}: AlignJustifyIconProps) => {
+export const TextAlignJustifyIcon = ({ color, style, ...props}: TextAlignJustifyIconProps) => {
const propsStyles = {"color": color};
const customStyles = {};
const styles = {...propsStyles, ...customStyles, ...style}
diff --git a/libs/components/icons/src/auto-icons/align-left/align-left.svg b/libs/components/icons/src/auto-icons/text-align-left/text-align-left.svg
similarity index 100%
rename from libs/components/icons/src/auto-icons/align-left/align-left.svg
rename to libs/components/icons/src/auto-icons/text-align-left/text-align-left.svg
diff --git a/libs/components/icons/src/auto-icons/align-left/align-left.tsx b/libs/components/icons/src/auto-icons/text-align-left/text-align-left.tsx
similarity index 74%
rename from libs/components/icons/src/auto-icons/align-left/align-left.tsx
rename to libs/components/icons/src/auto-icons/text-align-left/text-align-left.tsx
index d697280cac..ea8354f8e1 100644
--- a/libs/components/icons/src/auto-icons/align-left/align-left.tsx
+++ b/libs/components/icons/src/auto-icons/text-align-left/text-align-left.tsx
@@ -2,11 +2,11 @@
// eslint-disable-next-line no-restricted-imports
import { SvgIcon, SvgIconProps } from '@mui/material';
-export interface AlignLeftIconProps extends Omit {
+export interface TextAlignLeftIconProps extends Omit {
color?: string
}
-export const AlignLeftIcon = ({ color, style, ...props}: AlignLeftIconProps) => {
+export const TextAlignLeftIcon = ({ color, style, ...props}: TextAlignLeftIconProps) => {
const propsStyles = {"color": color};
const customStyles = {};
const styles = {...propsStyles, ...customStyles, ...style}
diff --git a/libs/components/icons/src/auto-icons/align-right/align-right.svg b/libs/components/icons/src/auto-icons/text-align-right/text-align-right.svg
similarity index 100%
rename from libs/components/icons/src/auto-icons/align-right/align-right.svg
rename to libs/components/icons/src/auto-icons/text-align-right/text-align-right.svg
diff --git a/libs/components/icons/src/auto-icons/align-right/align-right.tsx b/libs/components/icons/src/auto-icons/text-align-right/text-align-right.tsx
similarity index 73%
rename from libs/components/icons/src/auto-icons/align-right/align-right.tsx
rename to libs/components/icons/src/auto-icons/text-align-right/text-align-right.tsx
index 759688c4ec..33aa3226b8 100644
--- a/libs/components/icons/src/auto-icons/align-right/align-right.tsx
+++ b/libs/components/icons/src/auto-icons/text-align-right/text-align-right.tsx
@@ -2,11 +2,11 @@
// eslint-disable-next-line no-restricted-imports
import { SvgIcon, SvgIconProps } from '@mui/material';
-export interface AlignRightIconProps extends Omit {
+export interface TextAlignRightIconProps extends Omit {
color?: string
}
-export const AlignRightIcon = ({ color, style, ...props}: AlignRightIconProps) => {
+export const TextAlignRightIcon = ({ color, style, ...props}: TextAlignRightIconProps) => {
const propsStyles = {"color": color};
const customStyles = {};
const styles = {...propsStyles, ...customStyles, ...style}
diff --git a/libs/components/layout/src/header/EditorBoardSwitcher/StatusIcon.tsx b/libs/components/layout/src/header/EditorBoardSwitcher/StatusIcon.tsx
index 0c38b3f4e7..e7008da3df 100644
--- a/libs/components/layout/src/header/EditorBoardSwitcher/StatusIcon.tsx
+++ b/libs/components/layout/src/header/EditorBoardSwitcher/StatusIcon.tsx
@@ -1,5 +1,5 @@
+import { BoardViewIcon, DocViewIcon } from '@toeverything/components/icons';
import { styled } from '@toeverything/components/ui';
-import { DocViewIcon, BoardViewIcon } from '@toeverything/components/icons';
import { DocMode } from './type';
interface StatusIconProps {
diff --git a/libs/components/layout/src/header/EditorBoardSwitcher/StatusTrack.tsx b/libs/components/layout/src/header/EditorBoardSwitcher/StatusTrack.tsx
index 6fa7ac73f4..11eba1f663 100644
--- a/libs/components/layout/src/header/EditorBoardSwitcher/StatusTrack.tsx
+++ b/libs/components/layout/src/header/EditorBoardSwitcher/StatusTrack.tsx
@@ -1,6 +1,6 @@
-import type { DocMode } from './type';
import { styled } from '@toeverything/components/ui';
import { StatusIcon } from './StatusIcon';
+import type { DocMode } from './type';
interface StatusTrackProps {
mode: DocMode;
diff --git a/libs/components/layout/src/header/EditorBoardSwitcher/Switcher.tsx b/libs/components/layout/src/header/EditorBoardSwitcher/Switcher.tsx
index d373850446..6c8ab70372 100644
--- a/libs/components/layout/src/header/EditorBoardSwitcher/Switcher.tsx
+++ b/libs/components/layout/src/header/EditorBoardSwitcher/Switcher.tsx
@@ -1,10 +1,10 @@
-import { useLocation, useParams, useNavigate } from 'react-router-dom';
import { styled } from '@toeverything/components/ui';
+import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { StatusText } from './StatusText';
import { StatusTrack } from './StatusTrack';
import { DocMode } from './type';
-const isBoard = (pathname: string): boolean => pathname.endsWith('/whiteboard');
+const isBoard = (pathname: string): boolean => pathname.endsWith('/edgeless');
export const Switcher = () => {
const navigate = useNavigate();
@@ -20,11 +20,11 @@ export const Switcher = () => {
/**
* There are two possible modes:
* Page mode: /{workspaceId}/{pageId}
- * Board mode: /{workspaceId}/{pageId}/whiteboard
+ * Board mode: /{workspaceId}/{pageId}/edgeless
*/
const pageId = params['*'].split('/')[0];
const targetUrl = `/${workspaceId}/${pageId}${
- targetViewMode === DocMode.board ? '/whiteboard' : ''
+ targetViewMode === DocMode.board ? '/edgeless' : ''
}`;
navigate(targetUrl);
};
diff --git a/libs/components/layout/src/header/FileSystem.tsx b/libs/components/layout/src/header/FileSystem.tsx
index 83c638c5b3..016b26d1c4 100644
--- a/libs/components/layout/src/header/FileSystem.tsx
+++ b/libs/components/layout/src/header/FileSystem.tsx
@@ -1,10 +1,9 @@
-/* eslint-disable filename-rules/match */
import { useCallback, useMemo, useState } from 'react';
+import { CloseIcon } from '@toeverything/components/common';
import { IconButton, MuiSnackbar, styled } from '@toeverything/components/ui';
import { services } from '@toeverything/datasource/db-service';
import { useLocalTrigger } from '@toeverything/datasource/state';
-import { CloseIcon } from '@toeverything/components/common';
const cleanupWorkspace = (workspace: string) =>
new Promise((resolve, reject) => {
diff --git a/libs/components/layout/src/header/Header.tsx b/libs/components/layout/src/header/Header.tsx
index baa3706747..0f9028b9ae 100644
--- a/libs/components/layout/src/header/Header.tsx
+++ b/libs/components/layout/src/header/Header.tsx
@@ -1,24 +1,23 @@
-import { useNavigate, useParams, useLocation } from 'react-router-dom';
-import MenuIconBak from '@mui/icons-material/Menu';
-import {
- useUserAndSpaces,
- useShowSpaceSidebar,
- useShowSettingsSidebar,
-} from '@toeverything/datasource/state';
+import { ListIcon, LogoLink, SpaceIcon } from '@toeverything/components/common';
+import { SideBarViewIcon } from '@toeverything/components/icons';
import {
MuiIconButton as IconButton,
styled,
Tooltip,
useTheme,
} from '@toeverything/components/ui';
-import { SideBarViewIcon } from '@toeverything/components/icons';
-import { LogoLink, ListIcon, SpaceIcon } from '@toeverything/components/common';
+import { useFlag } from '@toeverything/datasource/feature-flags';
+import {
+ useShowSettingsSidebar,
+ useShowSpaceSidebar,
+ useUserAndSpaces,
+} from '@toeverything/datasource/state';
+import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { PageHistoryPortal } from './PageHistoryPortal';
-import { PageSharePortal } from './PageSharePortal';
import { PageSettingPortal } from './PageSettingPortal';
+import { PageSharePortal } from './PageSharePortal';
import { CurrentPageTitle } from './Title';
import { UserMenuIcon } from './user-menu-icon';
-import { useFlag } from '@toeverything/datasource/feature-flags';
function hideAffineHeader(pathname: string): boolean {
return ['/', '/login', '/error/workspace', '/error/404', '/ui'].includes(
@@ -27,7 +26,7 @@ function hideAffineHeader(pathname: string): boolean {
}
type HeaderIconProps = {
- isWhiteboardView?: boolean;
+ isEdgelessView?: boolean;
};
export const AffineHeader = () => {
@@ -39,7 +38,7 @@ export const AffineHeader = () => {
const { toggleSettingsSidebar: toggleInfoSidebar } =
useShowSettingsSidebar();
const theme = useTheme();
- const isWhiteboardView = pathname.endsWith('/whiteboard');
+ const isEdgelessView = pathname.endsWith('/edgeless');
const pageHistoryPortalFlag = useFlag('BooleanPageHistoryPortal', false);
const pageSettingPortalFlag = useFlag('PageSettingPortal', false);
const BooleanPageSharePortal = useFlag('BooleanPageSharePortal', false);
@@ -78,9 +77,9 @@ export const AffineHeader = () => {
- isWhiteboardView
+ isEdgelessView
? navigate(
`/${
params['workspace_id'] ||
@@ -101,17 +100,17 @@ export const AffineHeader = () => {
-
+
- isWhiteboardView
+ isEdgelessView
? null
: navigate(
`/${
params['workspace_id'] ||
'space'
- }/${params['*']}` + '/whiteboard'
+ }/${params['*']}` + '/edgeless'
)
}
>
@@ -167,14 +166,14 @@ const StyledHeaderRight = styled('div')`
`;
const HeaderIcon = styled(IconButton, {
- shouldForwardProp: (prop: string) => prop !== 'isWhiteboardView',
-})(({ isWhiteboardView = false }) => ({
+ shouldForwardProp: (prop: string) => prop !== 'isEdgelessView',
+})(({ isEdgelessView = false }) => ({
color: '#98ACBD',
minWidth: 48,
width: 48,
height: 36,
borderRadius: '8px',
- ...(isWhiteboardView && {
+ ...(isEdgelessView && {
color: '#fff',
backgroundColor: '#3E6FDB',
'&:hover': {
diff --git a/libs/components/layout/src/header/LayoutHeader.tsx b/libs/components/layout/src/header/LayoutHeader.tsx
index 2bada5a362..2d6913ac60 100644
--- a/libs/components/layout/src/header/LayoutHeader.tsx
+++ b/libs/components/layout/src/header/LayoutHeader.tsx
@@ -1,19 +1,19 @@
import { useMemo } from 'react';
-import { IconButton, styled } from '@toeverything/components/ui';
import {
LogoIcon,
- SideBarViewIcon,
SearchIcon,
SideBarViewCloseIcon,
+ SideBarViewIcon,
} from '@toeverything/components/icons';
+import { IconButton, styled } from '@toeverything/components/ui';
import {
- useShowSettingsSidebar,
useLocalTrigger,
+ useShowSettingsSidebar,
} from '@toeverything/datasource/state';
import { EditorBoardSwitcher } from './EditorBoardSwitcher';
-import { fsApiSupported, FileSystem } from './FileSystem';
+import { FileSystem, fsApiSupported } from './FileSystem';
import { CurrentPageTitle } from './Title';
export const LayoutHeader = () => {
diff --git a/libs/components/layout/src/header/PageSettingPortal.tsx b/libs/components/layout/src/header/PageSettingPortal.tsx
index 9c33f8d3fd..452734ff3c 100644
--- a/libs/components/layout/src/header/PageSettingPortal.tsx
+++ b/libs/components/layout/src/header/PageSettingPortal.tsx
@@ -1,22 +1,22 @@
-import { useState, MouseEvent, useCallback, useEffect } from 'react';
import { services } from '@toeverything/datasource/db-service';
-import { useParams, useNavigate } from 'react-router-dom';
+import { useCallback, useEffect, useState } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
-import { copyToClipboard } from '@toeverything/utils';
import { MoreIcon } from '@toeverything/components/icons';
import {
- MuiSnackbar as Snackbar,
- Popover,
ListButton,
MuiDivider as Divider,
+ MuiSnackbar as Snackbar,
MuiSwitch as Switch,
+ Popover,
styled,
} from '@toeverything/components/ui';
-import { useUserAndSpaces } from '@toeverything/datasource/state';
-import format from 'date-fns/format';
import { useFlag } from '@toeverything/datasource/feature-flags';
-import { PageBlock } from './types';
+import { useUserAndSpaces } from '@toeverything/datasource/state';
+import { copyToClipboard } from '@toeverything/utils';
+import format from 'date-fns/format';
import { FileExporter } from './file-exporter/file-exporter';
+import { PageBlock } from './types';
const PageSettingPortalContainer = styled('div')({
width: '320p',
padding: '15px',
diff --git a/libs/components/layout/src/header/PageSharePortal.tsx b/libs/components/layout/src/header/PageSharePortal.tsx
index d311b403b8..ea5fdcddeb 100644
--- a/libs/components/layout/src/header/PageSharePortal.tsx
+++ b/libs/components/layout/src/header/PageSharePortal.tsx
@@ -1,18 +1,17 @@
-import style9 from 'style9';
-import LanguageIcon from '@mui/icons-material/Language';
-import { useState, MouseEvent } from 'react';
import InsertLinkIcon from '@mui/icons-material/InsertLink';
+import LanguageIcon from '@mui/icons-material/Language';
import ShareIcon from '@mui/icons-material/Share';
import {
- MuiSnackbar as Snackbar,
MuiButton as Button,
- MuiDivider as Divider,
MuiInputBase as InputBase,
MuiPaper as Paper,
+ MuiSnackbar as Snackbar,
MuiSwitch as Switch,
Popover,
} from '@toeverything/components/ui';
import { copyToClipboard } from '@toeverything/utils';
+import { useState } from 'react';
+import style9 from 'style9';
const styles = style9.create({
pageShareBox: {
diff --git a/libs/components/layout/src/header/Title.tsx b/libs/components/layout/src/header/Title.tsx
index 61f2d3a246..0447cd52f6 100644
--- a/libs/components/layout/src/header/Title.tsx
+++ b/libs/components/layout/src/header/Title.tsx
@@ -1,6 +1,6 @@
-import { useEffect, useState, useCallback } from 'react';
+import { styled, Typography } from '@toeverything/components/ui';
+import { useCallback, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
-import { Typography, styled } from '@toeverything/components/ui';
import { services } from '@toeverything/datasource/db-service';
import { useUserAndSpaces } from '@toeverything/datasource/state';
diff --git a/libs/components/layout/src/header/file-exporter/file-exporter.ts b/libs/components/layout/src/header/file-exporter/file-exporter.ts
index ccbe9bc5f5..7fea0ea2fd 100644
--- a/libs/components/layout/src/header/file-exporter/file-exporter.ts
+++ b/libs/components/layout/src/header/file-exporter/file-exporter.ts
@@ -1,4 +1,3 @@
-import { PageBlock } from '../types';
import TurndownService from 'turndown';
const FileExporter = {
exportFile: (filename: string, text: string, format: string) => {
diff --git a/libs/components/layout/src/header/user-menu-icon/UserMenuList.tsx b/libs/components/layout/src/header/user-menu-icon/UserMenuList.tsx
index cee1d7e2ab..6e8d93303a 100644
--- a/libs/components/layout/src/header/user-menu-icon/UserMenuList.tsx
+++ b/libs/components/layout/src/header/user-menu-icon/UserMenuList.tsx
@@ -1,14 +1,14 @@
-import { useMemo } from 'react';
import { getAuth, signOut } from 'firebase/auth';
+import { useMemo } from 'react';
-import { LOGOUT_COOKIES, LOGOUT_LOCAL_STORAGE } from '@toeverything/utils';
-import { useUserAndSpaces } from '@toeverything/datasource/state';
import {
MuiDivider as Divider,
MuiList as List,
MuiListItem as ListItem,
MuiListItemText as ListItemText,
} from '@toeverything/components/ui';
+import { useUserAndSpaces } from '@toeverything/datasource/state';
+import { LOGOUT_COOKIES, LOGOUT_LOCAL_STORAGE } from '@toeverything/utils';
export const UserMenuList = () => {
const { user } = useUserAndSpaces();
diff --git a/libs/components/layout/src/settings-sidebar/Comments/CommentItem.tsx b/libs/components/layout/src/settings-sidebar/Comments/CommentItem.tsx
index 2ac99e7185..0351529760 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/CommentItem.tsx
+++ b/libs/components/layout/src/settings-sidebar/Comments/CommentItem.tsx
@@ -1,10 +1,10 @@
-import { Fragment, useState, useEffect, useCallback } from 'react';
-import { styled, MuiClickAwayListener } from '@toeverything/components/ui';
+import { MuiClickAwayListener, styled } from '@toeverything/components/ui';
import { services } from '@toeverything/datasource/db-service';
+import { Fragment, useCallback, useEffect, useState } from 'react';
import { QuotedContent } from './item/QuotedContent';
-import { ReplyItem } from './item/ReplyItem';
import { ReplyInput } from './item/ReplyInput';
+import { ReplyItem } from './item/ReplyItem';
import { CommentInfo } from './type';
export const CommentItem = (props: CommentInfo) => {
diff --git a/libs/components/layout/src/settings-sidebar/Comments/Comments.tsx b/libs/components/layout/src/settings-sidebar/Comments/Comments.tsx
index 3d03e3e82f..e2aeb949eb 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/Comments.tsx
+++ b/libs/components/layout/src/settings-sidebar/Comments/Comments.tsx
@@ -1,6 +1,6 @@
import { styled } from '@toeverything/components/ui';
-import { useComments } from './use-comments';
import { CommentItem } from './CommentItem';
+import { useComments } from './use-comments';
type CommentsProps = {
activeCommentId: string;
diff --git a/libs/components/layout/src/settings-sidebar/Comments/item/CommentedByUser.tsx b/libs/components/layout/src/settings-sidebar/Comments/item/CommentedByUser.tsx
index 97e7be1977..2aa1a3efbf 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/item/CommentedByUser.tsx
+++ b/libs/components/layout/src/settings-sidebar/Comments/item/CommentedByUser.tsx
@@ -1,7 +1,7 @@
-import { useMemo } from 'react';
-import { styled, MuiAvatar as Avatar } from '@toeverything/components/ui';
+import { MuiAvatar as Avatar, styled } from '@toeverything/components/ui';
import { useUserAndSpaces } from '@toeverything/datasource/state';
import { getUserDisplayName } from '@toeverything/utils';
+import { useMemo } from 'react';
type CommentedByUserProps = {
username: string;
diff --git a/libs/components/layout/src/settings-sidebar/Comments/item/QuotedContent.tsx b/libs/components/layout/src/settings-sidebar/Comments/item/QuotedContent.tsx
index 0e50baafc7..3756580c76 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/item/QuotedContent.tsx
+++ b/libs/components/layout/src/settings-sidebar/Comments/item/QuotedContent.tsx
@@ -1,5 +1,5 @@
-import { styled } from '@toeverything/components/ui';
import { DoneIcon } from '@toeverything/components/icons';
+import { styled } from '@toeverything/components/ui';
type QuotedContentProps = {
content: string;
diff --git a/libs/components/layout/src/settings-sidebar/Comments/item/ReplyInput.tsx b/libs/components/layout/src/settings-sidebar/Comments/item/ReplyInput.tsx
index b9e7015dca..2ccf8c1ece 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/item/ReplyInput.tsx
+++ b/libs/components/layout/src/settings-sidebar/Comments/item/ReplyInput.tsx
@@ -1,10 +1,10 @@
-import {
- useState,
- useCallback,
- KeyboardEventHandler,
- ChangeEvent,
-} from 'react';
import { styled } from '@toeverything/components/ui';
+import {
+ ChangeEvent,
+ KeyboardEventHandler,
+ useCallback,
+ useState,
+} from 'react';
export const ReplyInput = (props: any) => {
const { onSubmit } = props;
diff --git a/libs/components/layout/src/settings-sidebar/Comments/item/ReplyItem.tsx b/libs/components/layout/src/settings-sidebar/Comments/item/ReplyItem.tsx
index 30edeb9ca8..4879d672cb 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/item/ReplyItem.tsx
+++ b/libs/components/layout/src/settings-sidebar/Comments/item/ReplyItem.tsx
@@ -1,4 +1,3 @@
-import { styled } from '@toeverything/components/ui';
import type { CommentReply } from '@toeverything/datasource/db-service';
import { CommentContent } from './CommentContent';
diff --git a/libs/components/layout/src/settings-sidebar/Comments/use-comments.ts b/libs/components/layout/src/settings-sidebar/Comments/use-comments.ts
index 18d3db4bce..510b4e1bfb 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/use-comments.ts
+++ b/libs/components/layout/src/settings-sidebar/Comments/use-comments.ts
@@ -1,11 +1,11 @@
-import { useState, useCallback, useEffect, useMemo } from 'react';
-import { useParams } from 'react-router-dom';
-import { services } from '@toeverything/datasource/db-service';
import type { Virgo } from '@toeverything/components/editor-core';
+import { services } from '@toeverything/datasource/db-service';
import {
useCurrentEditors,
useShowSettingsSidebar,
} from '@toeverything/datasource/state';
+import { useCallback, useEffect, useMemo, useState } from 'react';
+import { useParams } from 'react-router-dom';
import type { CommentInfo } from './type';
export const useComments = () => {
diff --git a/libs/components/layout/src/settings-sidebar/Comments/utils.ts b/libs/components/layout/src/settings-sidebar/Comments/utils.ts
index 560f73a09a..2588bde5c6 100644
--- a/libs/components/layout/src/settings-sidebar/Comments/utils.ts
+++ b/libs/components/layout/src/settings-sidebar/Comments/utils.ts
@@ -1,6 +1,6 @@
import type {
- ReturnEditorBlock,
Comment,
+ ReturnEditorBlock,
} from '@toeverything/datasource/db-service';
export const getCommentsFromEditorBlocks = (
diff --git a/libs/components/layout/src/settings-sidebar/ContainerTabs/ContainerTabs.tsx b/libs/components/layout/src/settings-sidebar/ContainerTabs/ContainerTabs.tsx
index 404af63c9f..dc5320c19d 100644
--- a/libs/components/layout/src/settings-sidebar/ContainerTabs/ContainerTabs.tsx
+++ b/libs/components/layout/src/settings-sidebar/ContainerTabs/ContainerTabs.tsx
@@ -1,13 +1,13 @@
-import { cloneElement, useMemo, useCallback, type ReactElement } from 'react';
-import { styled } from '@toeverything/components/ui';
import {
CommentIcon,
LayoutIcon,
SettingsIcon,
} from '@toeverything/components/icons';
-import { LayoutSettings } from '../Layout';
+import { styled } from '@toeverything/components/ui';
+import { cloneElement, useCallback, useMemo, type ReactElement } from 'react';
import { Comments } from '../Comments';
import { useActiveComment } from '../Comments/use-comments';
+import { LayoutSettings } from '../Layout';
import { SettingsPanel } from '../Settings';
import { TabItemTitle } from './TabItemTitle';
import { useTabs } from './use-tabs';
diff --git a/libs/components/layout/src/settings-sidebar/ContainerTabs/TabItemTitle.tsx b/libs/components/layout/src/settings-sidebar/ContainerTabs/TabItemTitle.tsx
index 899b9b25a0..4dc7166d59 100644
--- a/libs/components/layout/src/settings-sidebar/ContainerTabs/TabItemTitle.tsx
+++ b/libs/components/layout/src/settings-sidebar/ContainerTabs/TabItemTitle.tsx
@@ -1,5 +1,5 @@
+import { ListIcon, ListItem, styled } from '@toeverything/components/ui';
import type { ReactNode } from 'react';
-import { styled, ListItem, ListIcon } from '@toeverything/components/ui';
type TabItemTitleProps = {
icon: ReactNode;
diff --git a/libs/components/layout/src/settings-sidebar/ContainerTabs/use-tabs.ts b/libs/components/layout/src/settings-sidebar/ContainerTabs/use-tabs.ts
index dad121a838..c1dc07cc28 100644
--- a/libs/components/layout/src/settings-sidebar/ContainerTabs/use-tabs.ts
+++ b/libs/components/layout/src/settings-sidebar/ContainerTabs/use-tabs.ts
@@ -1,4 +1,4 @@
-import { useRef, useEffect, useState, useMemo } from 'react';
+import { useEffect, useMemo, useRef, useState } from 'react';
function usePrevious(value: T) {
const ref = useRef();
diff --git a/libs/components/layout/src/settings-sidebar/Settings/SettingsList.tsx b/libs/components/layout/src/settings-sidebar/Settings/SettingsList.tsx
index 56528159d0..57e4a2fbf0 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/SettingsList.tsx
+++ b/libs/components/layout/src/settings-sidebar/Settings/SettingsList.tsx
@@ -1,4 +1,4 @@
-import { styled, ListItem, Divider, Switch } from '@toeverything/components/ui';
+import { Divider, ListItem, styled, Switch } from '@toeverything/components/ui';
import { useSettings } from './use-settings';
export const SettingsList = () => {
diff --git a/libs/components/layout/src/settings-sidebar/Settings/SettingsPanel.tsx b/libs/components/layout/src/settings-sidebar/Settings/SettingsPanel.tsx
index c3d3b516ea..1f392eedb7 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/SettingsPanel.tsx
+++ b/libs/components/layout/src/settings-sidebar/Settings/SettingsPanel.tsx
@@ -1,6 +1,6 @@
import { styled } from '@toeverything/components/ui';
-import { SettingsList } from './SettingsList';
import { Footer } from './footer';
+import { SettingsList } from './SettingsList';
export const SettingsPanel = () => {
return (
diff --git a/libs/components/layout/src/settings-sidebar/Settings/footer/LastModified.tsx b/libs/components/layout/src/settings-sidebar/Settings/footer/LastModified.tsx
index 6619d0191f..1bcf8a83be 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/footer/LastModified.tsx
+++ b/libs/components/layout/src/settings-sidebar/Settings/footer/LastModified.tsx
@@ -1,6 +1,6 @@
-import format from 'date-fns/format';
-import { Typography, styled } from '@toeverything/components/ui';
+import { styled, Typography } from '@toeverything/components/ui';
import { useUserAndSpaces } from '@toeverything/datasource/state';
+import format from 'date-fns/format';
import { usePageLastUpdated, useWorkspaceAndPageId } from '../util';
export const LastModified = () => {
diff --git a/libs/components/layout/src/settings-sidebar/Settings/footer/Logout.tsx b/libs/components/layout/src/settings-sidebar/Settings/footer/Logout.tsx
index 2c2d429034..a168f25b6d 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/footer/Logout.tsx
+++ b/libs/components/layout/src/settings-sidebar/Settings/footer/Logout.tsx
@@ -1,10 +1,5 @@
import { MoveToIcon } from '@toeverything/components/icons';
-import {
- ListItem,
- ListIcon,
- styled,
- Typography,
-} from '@toeverything/components/ui';
+import { ListItem, styled, Typography } from '@toeverything/components/ui';
import { LOGOUT_COOKIES, LOGOUT_LOCAL_STORAGE } from '@toeverything/utils';
import { getAuth, signOut } from 'firebase/auth';
diff --git a/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts b/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts
index 639afef92b..0dd9413c89 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts
+++ b/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts
@@ -1,17 +1,17 @@
-import { useNavigate } from 'react-router-dom';
import { message } from '@toeverything/components/ui';
-import { useSettingFlags, type SettingFlags } from './use-setting-flags';
import { copyToClipboard } from '@toeverything/utils';
+import { useNavigate } from 'react-router-dom';
+import { useSettingFlags, type SettingFlags } from './use-setting-flags';
import {
- duplicatePage,
- getPageTitle,
- exportHtml,
- exportMarkdown,
- importWorkspace,
- exportWorkspace,
- useWorkspaceAndPageId,
// useReadingMode,
clearWorkspace,
+ duplicatePage,
+ exportHtml,
+ exportMarkdown,
+ exportWorkspace,
+ getPageTitle,
+ importWorkspace,
+ useWorkspaceAndPageId,
} from './util';
interface BaseSettingItem {
diff --git a/libs/components/layout/src/settings-sidebar/Settings/util/get-page-info.ts b/libs/components/layout/src/settings-sidebar/Settings/util/get-page-info.ts
index d945c751a4..95054e5dc3 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/util/get-page-info.ts
+++ b/libs/components/layout/src/settings-sidebar/Settings/util/get-page-info.ts
@@ -1,5 +1,5 @@
-import { useState, useEffect } from 'react';
import { services } from '@toeverything/datasource/db-service';
+import { useEffect, useState } from 'react';
const UNTITLED = 'untitled';
diff --git a/libs/components/layout/src/settings-sidebar/Settings/util/handle-export.ts b/libs/components/layout/src/settings-sidebar/Settings/util/handle-export.ts
index ca667e22b4..fe284b986c 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/util/handle-export.ts
+++ b/libs/components/layout/src/settings-sidebar/Settings/util/handle-export.ts
@@ -1,5 +1,5 @@
-import { ClipboardParse } from '@toeverything/components/editor-core';
import { createEditor } from '@toeverything/components/affine-editor';
+import { ClipboardParse } from '@toeverything/components/editor-core';
import { fileExporter } from './file-exporter';
interface CreateClipboardParseProps {
diff --git a/libs/components/layout/src/settings-sidebar/Settings/util/index.ts b/libs/components/layout/src/settings-sidebar/Settings/util/index.ts
index 0068aad56b..792a6a74cc 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/util/index.ts
+++ b/libs/components/layout/src/settings-sidebar/Settings/util/index.ts
@@ -1,10 +1,10 @@
export { duplicatePage } from './duplicate-page';
-export { exportHtml, exportMarkdown } from './handle-export';
export { getPageTitle, usePageLastUpdated } from './get-page-info';
+export { exportHtml, exportMarkdown } from './handle-export';
export {
- importWorkspace,
- exportWorkspace,
clearWorkspace,
+ exportWorkspace,
+ importWorkspace,
} from './inspector-workspace';
-export { useWorkspaceAndPageId } from './use-workspace-page';
export { useReadingMode } from './use-reading-mode';
+export { useWorkspaceAndPageId } from './use-workspace-page';
diff --git a/libs/components/layout/src/workspace-sidebar/activities/activities.tsx b/libs/components/layout/src/workspace-sidebar/activities/activities.tsx
index 50c552c0ad..ffef663a81 100644
--- a/libs/components/layout/src/workspace-sidebar/activities/activities.tsx
+++ b/libs/components/layout/src/workspace-sidebar/activities/activities.tsx
@@ -1,15 +1,14 @@
-import { services } from '@toeverything/datasource/db-service';
-import { useUserAndSpaces } from '@toeverything/datasource/state';
-import { useCallback, useEffect, useState } from 'react';
-import { styled } from '@toeverything/components/ui';
import {
MuiList as List,
MuiListItem as ListItem,
MuiListItemText as ListItemText,
- MuiListItemButton as ListItemButton,
+ styled,
} from '@toeverything/components/ui';
-import { useNavigate } from 'react-router';
+import { services } from '@toeverything/datasource/db-service';
+import { useUserAndSpaces } from '@toeverything/datasource/state';
import { formatDistanceToNow } from 'date-fns';
+import { useCallback, useEffect, useState } from 'react';
+import { useNavigate } from 'react-router';
import { DotIcon } from '../dot-icon';
const StyledWrapper = styled('div')({
diff --git a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/CalendarHeatmap.tsx b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/CalendarHeatmap.tsx
index ca737f58c9..bdbe1f10f0 100644
--- a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/CalendarHeatmap.tsx
+++ b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/CalendarHeatmap.tsx
@@ -1,13 +1,12 @@
-import { ComponentType, useEffect } from 'react';
import {
- styled,
- MuiBox as Box,
- MuiTextField as TextField,
+ AdapterDateFns,
// CalendarPickerSkeleton,
LocalizationProvider,
- AdapterDateFns,
+ MuiBox as Box,
+ MuiTextField as TextField,
StaticDatePicker,
} from '@toeverything/components/ui';
+import { useEffect } from 'react';
import type { Theme } from './types';
import { useCalendarHeatmap } from './use-calendar-heatmap';
diff --git a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/HeatedDay.tsx b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/HeatedDay.tsx
index 6762b841f4..194e4de528 100644
--- a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/HeatedDay.tsx
+++ b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/HeatedDay.tsx
@@ -1,9 +1,9 @@
-import type { ComponentType } from 'react';
import {
- styled,
PickersDay,
+ styled,
type PickersDayProps,
} from '@toeverything/components/ui';
+import type { ComponentType } from 'react';
import type { Theme } from './types';
import { DEFAULT_THEME } from './utils';
diff --git a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/use-calendar-heatmap.ts b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/use-calendar-heatmap.ts
index 830a4d9cd7..9307e18665 100644
--- a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/use-calendar-heatmap.ts
+++ b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/use-calendar-heatmap.ts
@@ -1,11 +1,10 @@
-import { useCallback, useEffect, useState, createElement } from 'react';
-import { atom, useAtom } from 'jotai';
import type { PickersDayProps } from '@toeverything/components/ui';
+import { atom, useAtom } from 'jotai';
+import { createElement, useCallback, useState } from 'react';
-import type { CalendarDay } from './types';
import type { CalendarHeatmapProps } from './CalendarHeatmap';
import { HeatedDay } from './HeatedDay';
-import { fakeFetch, fetchActivitiesHeatmap } from './utils';
+import type { CalendarDay } from './types';
// import { usePageTree } from 'PageTree';
const highlightedDaysAtom = atom([]);
diff --git a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/utils.ts b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/utils.ts
index 428d4999d7..6b440103f0 100644
--- a/libs/components/layout/src/workspace-sidebar/calendar-heatmap/utils.ts
+++ b/libs/components/layout/src/workspace-sidebar/calendar-heatmap/utils.ts
@@ -6,7 +6,7 @@ import { getDateIsoStringWithTimezone } from '@toeverything/utils';
import getDaysInMonth from 'date-fns/getDaysInMonth';
import color, { ColorInput } from 'tinycolor2';
-import type { Theme, CalendarDay } from './types';
+import type { CalendarDay, Theme } from './types';
// export const DEFAULT_THEME = createCalendarTheme('#3E6FDB');
export const DEFAULT_THEME: Theme = {
diff --git a/libs/components/layout/src/workspace-sidebar/index.ts b/libs/components/layout/src/workspace-sidebar/index.ts
index 267622fe22..5c6a207f27 100644
--- a/libs/components/layout/src/workspace-sidebar/index.ts
+++ b/libs/components/layout/src/workspace-sidebar/index.ts
@@ -1,3 +1,3 @@
-export * from './page-tree';
-export * from './calendar-heatmap';
export * from './activities';
+export * from './calendar-heatmap';
+export * from './page-tree';
diff --git a/libs/components/layout/src/workspace-sidebar/page-tree/DndTree.tsx b/libs/components/layout/src/workspace-sidebar/page-tree/DndTree.tsx
index 6db19e3e86..2b9659d0c2 100755
--- a/libs/components/layout/src/workspace-sidebar/page-tree/DndTree.tsx
+++ b/libs/components/layout/src/workspace-sidebar/page-tree/DndTree.tsx
@@ -1,12 +1,12 @@
-import React, { useMemo } from 'react';
+import { useMemo } from 'react';
import {
+ defaultDropAnimation,
DndContext,
DragOverlay,
DropAnimation,
MeasuringStrategy,
PointerSensor,
- defaultDropAnimation,
useSensor,
useSensors,
} from '@dnd-kit/core';
diff --git a/libs/components/layout/src/workspace-sidebar/page-tree/index.ts b/libs/components/layout/src/workspace-sidebar/page-tree/index.ts
index 3e1ca6026d..836e68fa95 100644
--- a/libs/components/layout/src/workspace-sidebar/page-tree/index.ts
+++ b/libs/components/layout/src/workspace-sidebar/page-tree/index.ts
@@ -1,6 +1,5 @@
export { PageTree } from './PageTree';
+export * from './types';
export { usePageTree } from './use-page-tree';
-export * from './types';
-
// export { getRecentPages, setRecentPages } from './block-page';
diff --git a/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/DndTreeItem.tsx b/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/DndTreeItem.tsx
index 432c6e9a6f..e7990a5ee1 100755
--- a/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/DndTreeItem.tsx
+++ b/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/DndTreeItem.tsx
@@ -1,4 +1,4 @@
-import React, { CSSProperties } from 'react';
+import { CSSProperties } from 'react';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
diff --git a/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/NewFromTemplatePortal.tsx b/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/NewFromTemplatePortal.tsx
index c60864f341..5eee1bc1ac 100644
--- a/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/NewFromTemplatePortal.tsx
+++ b/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/NewFromTemplatePortal.tsx
@@ -1,26 +1,15 @@
-import React, {
- useState,
- MouseEvent,
- useCallback,
- useEffect,
- useRef,
-} from 'react';
import { services, TemplateFactory } from '@toeverything/datasource/db-service';
-import { useParams, useNavigate } from 'react-router-dom';
+import React, { useRef, useState } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
-import { copyToClipboard } from '@toeverything/utils';
-import { ViewSidebarIcon } from '@toeverything/components/common';
import {
- MuiSnackbar as Snackbar,
- MuiPopover as Popover,
- ListButton,
- MuiDivider as Divider,
- MuiSwitch as Switch,
- styled,
BaseButton,
+ ListButton,
+ MuiPopover as Popover,
+ styled,
} from '@toeverything/components/ui';
-import { useUserAndSpaces } from '@toeverything/datasource/state';
import { useFlag } from '@toeverything/datasource/feature-flags';
+import { useUserAndSpaces } from '@toeverything/datasource/state';
const NewFromTemplatePortalContainer = styled('div')({
width: '320p',
padding: '15px',
diff --git a/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/TreeItem.tsx b/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/TreeItem.tsx
index 334f2a504a..8ed5db75e8 100755
--- a/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/TreeItem.tsx
+++ b/libs/components/layout/src/workspace-sidebar/page-tree/tree-item/TreeItem.tsx
@@ -7,8 +7,8 @@ import { useParams } from 'react-router-dom';
import { useFlag } from '@toeverything/datasource/feature-flags';
-import MoreActions from './MoreActions';
import { DotIcon } from '../../dot-icon';
+import MoreActions from './MoreActions';
import {
ActionButton,
Counter,
diff --git a/libs/components/layout/src/workspace-sidebar/page-tree/use-page-tree.ts b/libs/components/layout/src/workspace-sidebar/page-tree/use-page-tree.ts
index 1cea945cc0..b088242ee2 100755
--- a/libs/components/layout/src/workspace-sidebar/page-tree/use-page-tree.ts
+++ b/libs/components/layout/src/workspace-sidebar/page-tree/use-page-tree.ts
@@ -1,13 +1,8 @@
-import { useCallback, useMemo, useState, useEffect } from 'react';
-import { useNavigate, useParams } from 'react-router-dom';
-import { atom, useAtom } from 'jotai';
-import type {
- DragEndEvent,
- DragMoveEvent,
- DragOverEvent,
- DragStartEvent,
-} from '@dnd-kit/core';
+import type { DragEndEvent, DragMoveEvent } from '@dnd-kit/core';
import { arrayMove } from '@dnd-kit/sortable';
+import { atom, useAtom } from 'jotai';
+import { useCallback, useEffect, useMemo, useState } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
import { services } from '@toeverything/datasource/db-service';
import type { DndTreeProps } from './DndTree';
diff --git a/libs/components/ui/src/PatchElements.tsx b/libs/components/ui/src/PatchElements.tsx
index c1326df98c..f0955a5dbc 100644
--- a/libs/components/ui/src/PatchElements.tsx
+++ b/libs/components/ui/src/PatchElements.tsx
@@ -1,6 +1,6 @@
-import type { ReactNode } from 'react';
-import { useState, Fragment } from 'react';
import { has } from '@toeverything/utils';
+import type { ReactNode } from 'react';
+import { Fragment, useState } from 'react';
export type UnPatchNode = () => void;
export type PatchNode = (key: string, node: ReactNode) => UnPatchNode;
diff --git a/libs/components/ui/src/autocomplete/index.tsx b/libs/components/ui/src/autocomplete/index.tsx
index b296cfb9d9..4ec36764b1 100644
--- a/libs/components/ui/src/autocomplete/index.tsx
+++ b/libs/components/ui/src/autocomplete/index.tsx
@@ -1,3 +1,3 @@
/* eslint-disable no-restricted-imports */
-export { autocompleteClasses } from '@mui/material/Autocomplete';
export { useAutocomplete } from '@mui/material';
+export { autocompleteClasses } from '@mui/material/Autocomplete';
diff --git a/libs/components/ui/src/button/IconButton.tsx b/libs/components/ui/src/button/IconButton.tsx
index 43773d46ba..88114f7b2c 100644
--- a/libs/components/ui/src/button/IconButton.tsx
+++ b/libs/components/ui/src/button/IconButton.tsx
@@ -1,11 +1,9 @@
import type {
- MouseEventHandler,
CSSProperties,
+ MouseEventHandler,
PropsWithChildren,
} from 'react';
import { styled } from '../styled';
-import { buttonStatus } from './constants';
-import { cx } from '../clsx';
/* Temporary solution, needs to be adjusted */
const SIZE_SMALL = 'small' as const;
@@ -29,13 +27,18 @@ const SIZE_CONFIG = {
type SizeType = keyof typeof SIZE_CONFIG;
-interface IconButtonProps {
+type IconButtonContainerProps = {
+ size?: SizeType;
+ hoverColor?: string; // CSSProperties['backgroundColor'];
+ backgroundColor?: string; // CSSProperties['backgroundColor'];
+ disabled?: boolean;
+};
+
+interface IconButtonProps extends IconButtonContainerProps {
onClick?: MouseEventHandler;
disabled?: boolean;
style?: CSSProperties;
className?: string;
- size?: SizeType;
- hoverColor?: string;
}
export const IconButton = ({
@@ -50,55 +53,40 @@ export const IconButton = ({
{...props}
onClick={disabled ? undefined : onClick}
disabled={disabled}
- className={cx({ [buttonStatus.disabled]: disabled }, className)}
>
{children}
);
};
-const Container = styled('button')<{
- size?: SizeType;
- hoverColor?: string;
-}>(({ theme, size = SIZE_MIDDLE, hoverColor }) => {
- const { iconSize, areaSize } = SIZE_CONFIG[size];
+const Container = styled('button')(
+ ({ theme, size = SIZE_MIDDLE, hoverColor, backgroundColor, disabled }) => {
+ const { iconSize, areaSize } = SIZE_CONFIG[size];
- return {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- width: areaSize,
- height: areaSize,
- backgroundColor: 'transparent',
- color: theme.affine.palette.icons,
- padding: theme.affine.spacing.iconPadding,
- borderRadius: '3px',
-
- '& svg': {
- width: iconSize,
- height: iconSize,
+ return {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
- },
+ width: areaSize,
+ height: areaSize,
+ backgroundColor: backgroundColor ?? 'transparent',
+ color: theme.affine.palette.icons,
+ padding: theme.affine.spacing.iconPadding,
+ borderRadius: '3px',
- '&:hover': {
- backgroundColor: hoverColor || theme.affine.palette.hover,
- },
+ '& svg': {
+ width: iconSize,
+ height: iconSize,
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
- [`&${buttonStatus.hover}`]: {
- backgroundColor: theme.affine.palette.hover,
- },
+ '&:hover': {
+ backgroundColor: hoverColor || theme.affine.palette.hover,
+ },
- '&:focus': {
- color: theme.affine.palette.primary,
- },
- [`&.${buttonStatus.focus}`]: {
- color: theme.affine.palette.primary,
- },
-
- [`&${buttonStatus.disabled}`]: {
- cursor: 'not-allowed',
- },
- };
-});
+ ...(disabled ? { cursor: 'not-allowed' } : {}),
+ };
+ }
+);
diff --git a/libs/components/ui/src/button/ListButton.tsx b/libs/components/ui/src/button/ListButton.tsx
index d29db359b4..30e5ca9a31 100644
--- a/libs/components/ui/src/button/ListButton.tsx
+++ b/libs/components/ui/src/button/ListButton.tsx
@@ -1,9 +1,7 @@
-import React from 'react';
import clsx from 'clsx';
import style9 from 'style9';
-
-import { BaseButton } from './base-button';
import { SvgIconProps } from '../svg-icon';
+import { BaseButton } from './base-button';
const styles = style9.create({
item: {
@@ -36,7 +34,7 @@ const styles = style9.create({
type ListButtonProps = {
className?: string;
- onClick: () => void;
+ onClick?: () => void;
onMouseOver?: () => void;
content?: string;
children?: () => JSX.Element;
diff --git a/libs/components/ui/src/button/constants.ts b/libs/components/ui/src/button/constants.ts
deleted file mode 100644
index 22ec35c5d1..0000000000
--- a/libs/components/ui/src/button/constants.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export const buttonStatus = {
- hover: '.hover',
- focus: '.focus',
- active: '.focus',
- disabled: '.disabled',
-};
diff --git a/libs/components/ui/src/button/index.ts b/libs/components/ui/src/button/index.ts
index bac4da3799..15fe2dce7e 100644
--- a/libs/components/ui/src/button/index.ts
+++ b/libs/components/ui/src/button/index.ts
@@ -1,3 +1,3 @@
export { BaseButton } from './base-button';
-export { ListButton } from './ListButton';
export { IconButton } from './IconButton';
+export { ListButton } from './ListButton';
diff --git a/libs/components/ui/src/cascader/Cascader.tsx b/libs/components/ui/src/cascader/Cascader.tsx
index ef486e5029..1ba44aab6b 100644
--- a/libs/components/ui/src/cascader/Cascader.tsx
+++ b/libs/components/ui/src/cascader/Cascader.tsx
@@ -1,12 +1,12 @@
-import { useRef, useState, ReactElement } from 'react';
+import { ArrowRightIcon } from '@toeverything/components/icons';
+import { ReactElement, useRef, useState } from 'react';
+import { Divider } from '../divider';
import {
MuiGrow as Grow,
MuiPopper as Popper,
MuiPopperPlacementType as PopperPlacementType,
} from '../mui';
import { styled } from '../styled';
-import { ArrowRightIcon } from '@toeverything/components/icons';
-import { Divider } from '../divider';
export interface CascaderItemProps {
title: string;
@@ -39,7 +39,7 @@ function CascaderItem(props: ItemProps) {
const [open, setOpen] = useState(false);
if (isDivide) {
- return ;
+ return ;
}
const on_click_item = () => {
diff --git a/libs/components/ui/src/checkbox/Checkbox.tsx b/libs/components/ui/src/checkbox/Checkbox.tsx
index e3d7121a4c..ee39f5572f 100644
--- a/libs/components/ui/src/checkbox/Checkbox.tsx
+++ b/libs/components/ui/src/checkbox/Checkbox.tsx
@@ -1,9 +1,8 @@
-import * as React from 'react';
/* eslint-disable no-restricted-imports */
import MuiCheckbox, { type CheckboxProps } from '@mui/material/Checkbox';
import {
- CheckBoxUncheckIcon,
CheckBoxCheckIcon,
+ CheckBoxUncheckIcon,
} from '@toeverything/components/icons';
import { styled } from '../styled';
diff --git a/libs/components/ui/src/date/Calendar.tsx b/libs/components/ui/src/date/Calendar.tsx
index 9104544b4a..e45c138b4f 100644
--- a/libs/components/ui/src/date/Calendar.tsx
+++ b/libs/components/ui/src/date/Calendar.tsx
@@ -1,4 +1,3 @@
-import React from 'react';
import {
Calendar as ReactCalendar,
type CalendarProps,
diff --git a/libs/components/ui/src/date/index.ts b/libs/components/ui/src/date/index.ts
index 3582a92041..b884e0bbb8 100644
--- a/libs/components/ui/src/date/index.ts
+++ b/libs/components/ui/src/date/index.ts
@@ -2,10 +2,9 @@ import 'react-date-range/dist/styles.css'; // main css file
import 'react-date-range/dist/theme/default.css'; // theme css file
// export { DateRange } from 'react-date-range';
-export { DateRange } from './DateRange';
export { Calendar } from './Calendar';
-
-export type { DateRangeProps, Range } from './DateRange';
export type { CalendarProps } from './Calendar';
+export { DateRange } from './DateRange';
+export type { DateRangeProps, Range } from './DateRange';
// export const NewDateRange = DateRange;
diff --git a/libs/components/ui/src/divider/Divider.tsx b/libs/components/ui/src/divider/Divider.tsx
index 86fc8ee923..d08e758759 100644
--- a/libs/components/ui/src/divider/Divider.tsx
+++ b/libs/components/ui/src/divider/Divider.tsx
@@ -1,7 +1,7 @@
-import type { ReactNode, CSSProperties } from 'react';
-import { styled } from '../styled';
-import { MuiDivider } from '../mui';
+import type { CSSProperties, ReactNode } from 'react';
import type { MuiDividerProps } from '../mui';
+import { MuiDivider } from '../mui';
+import { styled } from '../styled';
interface DividerProps {
orientation?: 'horizontal' | 'vertical';
diff --git a/libs/components/ui/src/event-away/index.ts b/libs/components/ui/src/event-away/index.ts
index 155e71ad5d..5903c3432b 100644
--- a/libs/components/ui/src/event-away/index.ts
+++ b/libs/components/ui/src/event-away/index.ts
@@ -1,4 +1,4 @@
-import { useState, useEffect, useRef } from 'react';
+import { useEffect, useRef, useState } from 'react';
type Equal =
// prettier-ignore
diff --git a/libs/components/ui/src/index.ts b/libs/components/ui/src/index.ts
index 7d55074540..fea8c1b041 100644
--- a/libs/components/ui/src/index.ts
+++ b/libs/components/ui/src/index.ts
@@ -1,52 +1,47 @@
// Base abstract feature for all UI components
-export { Theme, useTheme, withTheme, ThemeProvider } from './theme';
-export { styled, keyframes } from './styled';
-export type { SxProps } from './styled';
-
-export * from './mui';
-export * from './svg-icon';
-
-export { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
export { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
export { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
export {
PickersDay,
type PickersDayProps,
} from '@mui/x-date-pickers/PickersDay';
-
+export { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
+export { autocompleteClasses, useAutocomplete } from './autocomplete';
// Components
-export { BaseButton, ListButton, IconButton } from './button';
+export { BaseButton, IconButton, ListButton } from './button';
+export * from './cascader';
+export { Checkbox } from './checkbox';
+export type { CheckboxProps } from './checkbox';
+export { Clickable } from './clickable';
+export * from './clsx';
+export { Calendar, DateRange } from './date';
+export type { CalendarProps, DateRangeProps, Range } from './date';
+export { Divider } from './divider';
+export { Input } from './input';
+export type { InputProps } from './input';
+export { ListIcon, ListItem } from './list';
+export { message } from './message';
export { TransitionsModal } from './model';
+export * from './mui';
+export { usePatchNodes } from './PatchElements';
+export type { PatchNode, UnPatchNode } from './PatchElements';
export { Popover, PopoverContainer } from './popover';
export type { PopoverProps } from './popover';
export { Popper } from './popper';
-export type { PopperProps, PopperHandler } from './popper';
-
-export { OldSelect, Select, Option } from './select';
-export { message } from './message';
-export { Input } from './input';
-export type { InputProps } from './input';
-export { Tooltip } from './tooltip';
-export { usePatchNodes } from './PatchElements';
-export type { PatchNode, UnPatchNode } from './PatchElements';
-export { Tag } from './tag';
-export type { TagProps } from './tag';
-export { Divider } from './divider';
-export { autocompleteClasses, useAutocomplete } from './autocomplete';
-export { Slider } from './slider';
-export { Typography } from './typography';
-export { ListItem, ListIcon } from './list';
-export { Clickable } from './clickable';
-export { DateRange, Calendar } from './date';
-export type { DateRangeProps, Range, CalendarProps } from './date';
+export type { PopperHandler, PopperProps } from './popper';
export { Radio } from './radio';
export type { RadioProps } from './radio';
-export { Checkbox } from './checkbox';
-export type { CheckboxProps } from './checkbox';
-export * from './cascader';
-export { Switch } from './switch';
-export type { SwitchProps } from './switch';
+export { OldSelect, Option, Select } from './select';
+export { Slider } from './slider';
+export { keyframes, styled } from './styled';
+export type { SxProps } from './styled';
+export * from './svg-icon';
/* types */
export type { SvgIconProps } from './svg-icon';
-
-export * from './clsx';
+export { Switch } from './switch';
+export type { SwitchProps } from './switch';
+export { Tag } from './tag';
+export type { TagProps } from './tag';
+export { Theme, ThemeProvider, useTheme, withTheme } from './theme';
+export { Tooltip } from './tooltip';
+export { Typography } from './typography';
diff --git a/libs/components/ui/src/input/Input.tsx b/libs/components/ui/src/input/Input.tsx
index aeb5c97404..fff60cb069 100644
--- a/libs/components/ui/src/input/Input.tsx
+++ b/libs/components/ui/src/input/Input.tsx
@@ -1,8 +1,8 @@
import React, {
forwardRef,
+ type CSSProperties,
type ForwardedRef,
type InputHTMLAttributes,
- type CSSProperties,
} from 'react';
import { styled } from '../styled';
diff --git a/libs/components/ui/src/list/ListItem.tsx b/libs/components/ui/src/list/ListItem.tsx
index 080aff416f..39c3d90492 100644
--- a/libs/components/ui/src/list/ListItem.tsx
+++ b/libs/components/ui/src/list/ListItem.tsx
@@ -1,4 +1,4 @@
-import type { PropsWithChildren, CSSProperties } from 'react';
+import type { CSSProperties, PropsWithChildren } from 'react';
import { Clickable } from '../clickable';
import { styled } from '../styled';
diff --git a/libs/components/ui/src/list/index.ts b/libs/components/ui/src/list/index.ts
index bf332e9e8c..4a5fe5a433 100644
--- a/libs/components/ui/src/list/index.ts
+++ b/libs/components/ui/src/list/index.ts
@@ -1,2 +1,2 @@
-export { ListItem } from './ListItem';
export { ListIcon } from './ListIcon';
+export { ListItem } from './ListItem';
diff --git a/libs/components/ui/src/message/Message.tsx b/libs/components/ui/src/message/Message.tsx
index ecc9a8ad1c..fc25565471 100644
--- a/libs/components/ui/src/message/Message.tsx
+++ b/libs/components/ui/src/message/Message.tsx
@@ -1,15 +1,15 @@
import {
NotificationInstance,
+ type NotificationContent,
type NotificationController,
type NotificationInstanceProps,
- type NotificationContent,
- type NotificationOption,
type NotificationKey,
+ type NotificationOption,
} from '../notification';
import {
- SuccessMessage,
ErrorMessage,
InfoMessage,
+ SuccessMessage,
WarningMessage,
} from './MessageContent';
diff --git a/libs/components/ui/src/model/index.tsx b/libs/components/ui/src/model/index.tsx
index 7211dfed32..baeb5db9ac 100644
--- a/libs/components/ui/src/model/index.tsx
+++ b/libs/components/ui/src/model/index.tsx
@@ -1,7 +1,5 @@
-import { useState } from 'react';
-
-import { styled } from '@mui/system';
import ModalUnstyled from '@mui/base/ModalUnstyled';
+import { styled } from '@mui/system';
// eslint-disable-next-line no-restricted-imports
import Fade from '@mui/material/Fade';
diff --git a/libs/components/ui/src/mui.ts b/libs/components/ui/src/mui.ts
index 47588ce5e6..6b085e52d9 100644
--- a/libs/components/ui/src/mui.ts
+++ b/libs/components/ui/src/mui.ts
@@ -22,6 +22,7 @@ import {
Collapse,
Container,
Divider,
+ Fade,
FormControlLabel,
Grid,
Grow,
@@ -52,7 +53,6 @@ import {
tooltipClasses,
Typography,
Zoom,
- Fade,
} from '@mui/material';
export { alpha } from '@mui/system';
diff --git a/libs/components/ui/src/notification/Notification.tsx b/libs/components/ui/src/notification/Notification.tsx
index 7d4305c462..f980e816a4 100644
--- a/libs/components/ui/src/notification/Notification.tsx
+++ b/libs/components/ui/src/notification/Notification.tsx
@@ -1,12 +1,12 @@
-import React, { forwardRef, useImperativeHandle } from 'react';
+import { forwardRef, useImperativeHandle } from 'react';
import {
SnackbarProvider,
useSnackbar,
- type SnackbarProviderProps,
type OptionsObject,
- type SnackbarMessage,
type SnackbarKey,
+ type SnackbarMessage,
+ type SnackbarProviderProps,
} from 'notistack';
import { createRoot } from 'react-dom/client';
diff --git a/libs/components/ui/src/popover/Popover.tsx b/libs/components/ui/src/popover/Popover.tsx
index c165b45197..ec919811dc 100644
--- a/libs/components/ui/src/popover/Popover.tsx
+++ b/libs/components/ui/src/popover/Popover.tsx
@@ -1,8 +1,8 @@
+import { type PropsWithChildren } from 'react';
import type { MuiPopperPlacementType as PopperPlacementType } from '../mui';
-import React, { type PropsWithChildren } from 'react';
import { Popper } from '../popper';
import { PopoverContainer } from './Container';
-import type { PopoverProps, PopoverDirection } from './interface';
+import type { PopoverDirection, PopoverProps } from './interface';
export const placementToContainerDirection: Record<
PopperPlacementType,
diff --git a/libs/components/ui/src/popover/index.ts b/libs/components/ui/src/popover/index.ts
index 718c074cce..5f27c95d85 100644
--- a/libs/components/ui/src/popover/index.ts
+++ b/libs/components/ui/src/popover/index.ts
@@ -1,3 +1,3 @@
-export * from './Popover';
-export * from './interface';
export { PopoverContainer } from './Container';
+export * from './interface';
+export * from './Popover';
diff --git a/libs/components/ui/src/popover/interface.ts b/libs/components/ui/src/popover/interface.ts
index d26ebc7f48..15a332feae 100644
--- a/libs/components/ui/src/popover/interface.ts
+++ b/libs/components/ui/src/popover/interface.ts
@@ -1,4 +1,4 @@
-import type { ReactNode, CSSProperties } from 'react';
+import type { CSSProperties, ReactNode } from 'react';
import { PopperProps } from '../popper';
export type PopoverDirection =
diff --git a/libs/components/ui/src/popper/PopoverArrow.tsx b/libs/components/ui/src/popper/PopoverArrow.tsx
index 148202effc..61bd6de7e5 100644
--- a/libs/components/ui/src/popper/PopoverArrow.tsx
+++ b/libs/components/ui/src/popper/PopoverArrow.tsx
@@ -1,6 +1,6 @@
-import React, { forwardRef } from 'react';
-import { PopperArrowProps } from './interface';
+import { forwardRef } from 'react';
import { styled } from '../styled';
+import { PopperArrowProps } from './interface';
export const PopperArrow = forwardRef(
({ placement }, ref) => {
diff --git a/libs/components/ui/src/popper/Popper.tsx b/libs/components/ui/src/popper/Popper.tsx
index 4cf9f6a78b..924e3be8fd 100644
--- a/libs/components/ui/src/popper/Popper.tsx
+++ b/libs/components/ui/src/popper/Popper.tsx
@@ -1,4 +1,4 @@
-import React, {
+import {
useEffect,
useImperativeHandle,
useMemo,
@@ -171,7 +171,9 @@ const Container = styled('div')({
display: 'contents',
});
-const BasicStyledPopper = styled(PopperUnstyled)<{
+const BasicStyledPopper = styled(PopperUnstyled, {
+ shouldForwardProp: propName => !['zIndex'].some(name => name === propName),
+})<{
zIndex?: number;
}>(({ zIndex, theme }) => {
return {
diff --git a/libs/components/ui/src/popper/index.ts b/libs/components/ui/src/popper/index.ts
index 8d8b52cd2b..88fac67073 100644
--- a/libs/components/ui/src/popper/index.ts
+++ b/libs/components/ui/src/popper/index.ts
@@ -1,2 +1,2 @@
-export * from './Popper';
export * from './interface';
+export * from './Popper';
diff --git a/libs/components/ui/src/popper/interface.ts b/libs/components/ui/src/popper/interface.ts
index d60fac29f7..b449eff61f 100644
--- a/libs/components/ui/src/popper/interface.ts
+++ b/libs/components/ui/src/popper/interface.ts
@@ -1,8 +1,8 @@
import type { CSSProperties, ReactNode, Ref } from 'react';
/* eslint-disable no-restricted-imports */
import {
- type PopperUnstyledProps,
type PopperPlacementType,
+ type PopperUnstyledProps,
} from '@mui/base/PopperUnstyled';
export type VirtualElement = {
getBoundingClientRect: () => ClientRect | DOMRect;
diff --git a/libs/components/ui/src/radio/Radio.tsx b/libs/components/ui/src/radio/Radio.tsx
index f31a319f8e..ba97c6ca77 100644
--- a/libs/components/ui/src/radio/Radio.tsx
+++ b/libs/components/ui/src/radio/Radio.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
/* eslint-disable no-restricted-imports */
import MuiRadio, { type RadioProps } from '@mui/material/Radio';
import { styled } from '../styled';
diff --git a/libs/components/ui/src/select/OldSelect.tsx b/libs/components/ui/src/select/OldSelect.tsx
index 0c49c67c8a..5f3350a199 100644
--- a/libs/components/ui/src/select/OldSelect.tsx
+++ b/libs/components/ui/src/select/OldSelect.tsx
@@ -1,6 +1,6 @@
+import type { ChangeEvent, CSSProperties } from 'react';
import { useCallback } from 'react';
import { styled } from '../styled';
-import type { CSSProperties, ChangeEvent } from 'react';
/**
* WARNING: This component is about to be deprecated, use Select replace
diff --git a/libs/components/ui/src/select/Select.tsx b/libs/components/ui/src/select/Select.tsx
index 607c3bfa62..7dcfcdc45a 100644
--- a/libs/components/ui/src/select/Select.tsx
+++ b/libs/components/ui/src/select/Select.tsx
@@ -2,13 +2,13 @@ import {
forwardRef,
type CSSProperties,
type ForwardedRef,
- type RefAttributes,
type ReactNode,
+ type RefAttributes,
} from 'react';
/* eslint-disable no-restricted-imports */
import SelectUnstyled, {
- type SelectUnstyledProps,
selectUnstyledClasses,
+ type SelectUnstyledProps,
} from '@mui/base/SelectUnstyled';
/* eslint-disable no-restricted-imports */
import PopperUnstyled from '@mui/base/PopperUnstyled';
diff --git a/libs/components/ui/src/select/index.ts b/libs/components/ui/src/select/index.ts
index afea72a2b0..516e039935 100644
--- a/libs/components/ui/src/select/index.ts
+++ b/libs/components/ui/src/select/index.ts
@@ -1,4 +1,4 @@
-export { Select } from './Select';
+export { OldSelect } from './OldSelect';
export { Option } from './Option';
export { OptionGroup } from './OptionGroup';
-export { OldSelect } from './OldSelect';
+export { Select } from './Select';
diff --git a/libs/components/ui/src/slider/Slider.tsx b/libs/components/ui/src/slider/Slider.tsx
index b676ca1cab..88b1e92344 100644
--- a/libs/components/ui/src/slider/Slider.tsx
+++ b/libs/components/ui/src/slider/Slider.tsx
@@ -1,5 +1,5 @@
-import { SliderUnstyled, sliderUnstyledClasses } from '@mui/base';
import type { SliderUnstyledProps } from '@mui/base';
+import { SliderUnstyled, sliderUnstyledClasses } from '@mui/base';
import { alpha } from '@mui/system';
import { styled } from '../styled';
diff --git a/libs/components/ui/src/styled/index.ts b/libs/components/ui/src/styled/index.ts
index 9784a93951..6116b6cc25 100644
--- a/libs/components/ui/src/styled/index.ts
+++ b/libs/components/ui/src/styled/index.ts
@@ -1,8 +1,9 @@
-// eslint-disable-next-line no-restricted-imports
-import { styled as muiStyled, keyframes } from '@mui/material/styles';
-import { ReactHTML, ReactSVG } from 'react';
import isPropValid from '@emotion/is-prop-valid';
+// eslint-disable-next-line no-restricted-imports
+import { keyframes, styled as muiStyled } from '@mui/material/styles';
+import { ReactHTML, ReactSVG } from 'react';
export type { SxProps } from '@mui/system';
+export { keyframes };
// Props that will be passed to DOM
const ALLOW_LIST_PROPS: string[] = [];
@@ -71,5 +72,3 @@ export const styled: typeof muiStyled = (
options.shouldForwardProp = isValidProp;
return muiStyled(component, options);
};
-
-export { keyframes };
diff --git a/libs/components/ui/src/switch/Switch.tsx b/libs/components/ui/src/switch/Switch.tsx
index fd48070a63..b31c1828fe 100644
--- a/libs/components/ui/src/switch/Switch.tsx
+++ b/libs/components/ui/src/switch/Switch.tsx
@@ -1,7 +1,7 @@
-import type { CSSProperties } from 'react';
-import { styled } from '../styled';
import { useSwitch, UseSwitchParameters } from '@mui/base/SwitchUnstyled';
+import type { CSSProperties } from 'react';
import { ReactNode } from 'react';
+import { styled } from '../styled';
/**
* Switch is extend by mui SwitchUnstyled
diff --git a/libs/components/ui/src/tag/Tag.tsx b/libs/components/ui/src/tag/Tag.tsx
index 5c582b6da3..429e99422b 100644
--- a/libs/components/ui/src/tag/Tag.tsx
+++ b/libs/components/ui/src/tag/Tag.tsx
@@ -1,12 +1,7 @@
-import type {
- ChangeEventHandler,
- PropsWithChildren,
- CSSProperties,
- ReactNode,
-} from 'react';
+import type { CSSProperties, PropsWithChildren, ReactNode } from 'react';
-import { MouseEventHandler } from 'react';
import CloseIcon from '@mui/icons-material/Close';
+import { MouseEventHandler } from 'react';
import { StyledTag } from './style';
export interface TagProps {
diff --git a/libs/components/ui/src/theme/theme.ts b/libs/components/ui/src/theme/theme.ts
index b8055da052..76d42e3a0a 100644
--- a/libs/components/ui/src/theme/theme.ts
+++ b/libs/components/ui/src/theme/theme.ts
@@ -1,4 +1,3 @@
-import ColorObject from './color';
// import { ThemeOptions } from '@mui/material/styles';
/**
* @deprecated Please use the new {@link ThemeOptions} type.
diff --git a/libs/components/ui/src/theme/utils.tsx b/libs/components/ui/src/theme/utils.tsx
index c31f47d124..b99343a35f 100644
--- a/libs/components/ui/src/theme/utils.tsx
+++ b/libs/components/ui/src/theme/utils.tsx
@@ -1,10 +1,10 @@
-import type { PropsWithChildren, ReactNode } from 'react';
+import type { ReactNode } from 'react';
// eslint-disable-next-line no-restricted-imports
import {
createTheme,
+ Theme as MuiTheme,
ThemeProvider as MuiThemeProvider,
useTheme as muiUseTheme,
- Theme as MuiTheme,
} from '@mui/material/styles';
import type { ThemeOptions as AffineThemeOptions } from './theme';
import { Theme } from './theme';
diff --git a/libs/components/ui/src/tooltip/Tooltip.tsx b/libs/components/ui/src/tooltip/Tooltip.tsx
index ff0b47262c..ea34352744 100644
--- a/libs/components/ui/src/tooltip/Tooltip.tsx
+++ b/libs/components/ui/src/tooltip/Tooltip.tsx
@@ -1,8 +1,8 @@
-import { type PropsWithChildren, type CSSProperties } from 'react';
-import { type PopperProps, Popper } from '../popper';
-import { PopoverContainer, placementToContainerDirection } from '../popover';
-import type { TooltipProps } from './interface';
+import { type CSSProperties, type PropsWithChildren } from 'react';
+import { placementToContainerDirection, PopoverContainer } from '../popover';
+import { Popper, type PopperProps } from '../popper';
import { useTheme } from '../theme';
+import type { TooltipProps } from './interface';
const useTooltipStyle = (): CSSProperties => {
const theme = useTheme();
diff --git a/libs/datasource/db-service/src/index.ts b/libs/datasource/db-service/src/index.ts
index 304552820f..3d4ffb01a9 100644
--- a/libs/datasource/db-service/src/index.ts
+++ b/libs/datasource/db-service/src/index.ts
@@ -1,13 +1,48 @@
-import { diContainer, serviceMapByCallName } from './services';
import type { DbServicesMap } from './services';
-export type { Template } from './services/editor-block/templates/types';
+import { diContainer, serviceMapByCallName } from './services';
+export { Protocol } from './protocol';
+export {
+ ColumnType,
+ isBooleanColumn,
+ isContentColumn,
+ isDateColumn,
+ isEnumColumn,
+ isFileColumn,
+ isNumberColumn,
+ isStringColumn,
+} from './services';
+export type {
+ BlockFlavorKeys,
+ BlockFlavors,
+ BooleanColumn,
+ BooleanColumnValue,
+ Column,
+ ContentColumn,
+ ContentColumnValue,
+ CreateEditorBlock,
+ DateColumn,
+ DateColumnValue,
+ DefaultColumnsValue,
+ DeleteEditorBlock,
+ EnumColumn,
+ EnumColumnValue,
+ FileColumn,
+ FileColumnValue,
+ GetEditorBlock,
+ NumberColumn,
+ NumberColumnValue,
+ ReturnEditorBlock,
+ StringColumnValue,
+ UpdateEditorBlock,
+} from './services';
+export type { Comment, CommentReply } from './services/comment/types';
+export type { ReturnUnobserve } from './services/database';
export {
TemplateFactory,
type TemplateMeta,
} from './services/editor-block/templates';
-
-export type { ReturnUnobserve } from './services/database';
-export type { Comment, CommentReply } from './services/comment/types';
+export type { Template } from './services/editor-block/templates/types';
+export { DEFAULT_COLUMN_KEYS } from './services/editor-block/utils/column/default-config';
const api = new Proxy({} as DbServicesMap, {
get(target, prop) {
@@ -23,40 +58,3 @@ export const services = {
api,
};
(window as any)['services'] = services;
-
-export type {
- CreateEditorBlock,
- ReturnEditorBlock,
- GetEditorBlock,
- UpdateEditorBlock,
- DeleteEditorBlock,
- BlockFlavors,
- BlockFlavorKeys,
- Column,
- ContentColumn,
- NumberColumn,
- EnumColumn,
- DateColumn,
- BooleanColumn,
- FileColumn,
- DefaultColumnsValue,
- ContentColumnValue,
- NumberColumnValue,
- EnumColumnValue,
- BooleanColumnValue,
- DateColumnValue,
- FileColumnValue,
- StringColumnValue,
-} from './services';
-export {
- ColumnType,
- isBooleanColumn,
- isContentColumn,
- isDateColumn,
- isFileColumn,
- isNumberColumn,
- isEnumColumn,
- isStringColumn,
-} from './services';
-export { Protocol } from './protocol';
-export { DEFAULT_COLUMN_KEYS } from './services/editor-block/utils/column/default-config';
diff --git a/libs/datasource/db-service/src/protocol/index.ts b/libs/datasource/db-service/src/protocol/index.ts
index 606988c683..328cc03bc3 100644
--- a/libs/datasource/db-service/src/protocol/index.ts
+++ b/libs/datasource/db-service/src/protocol/index.ts
@@ -22,7 +22,6 @@ const Protocol = {
quote: 'quote',
toc: 'toc',
database: 'database',
- whiteboard: 'whiteboard',
template: 'template',
discussion: 'discussion',
comment: 'comment',
diff --git a/libs/datasource/db-service/src/services/base.ts b/libs/datasource/db-service/src/services/base.ts
index 9e10af9177..df0f7133a5 100644
--- a/libs/datasource/db-service/src/services/base.ts
+++ b/libs/datasource/db-service/src/services/base.ts
@@ -1,9 +1,9 @@
import {
BlockClientInstance,
- BlockInitOptions,
- BlockImplInstance,
- BlockMatcher,
BlockContentExporter,
+ BlockImplInstance,
+ BlockInitOptions,
+ BlockMatcher,
QueryIndexMetadata,
} from '@toeverything/datasource/jwt';
import { DependencyCallOrConstructProps } from '@toeverything/utils';
diff --git a/libs/datasource/db-service/src/services/comment/comment.ts b/libs/datasource/db-service/src/services/comment/comment.ts
index 968e201cc1..0c90f9691a 100644
--- a/libs/datasource/db-service/src/services/comment/comment.ts
+++ b/libs/datasource/db-service/src/services/comment/comment.ts
@@ -1,23 +1,23 @@
import { DependencyCallOrConstructProps } from '@toeverything/utils';
+import { WORKSPACE_COMMENTS } from '../../utils';
import type { ReturnUnobserve } from '../database/observer';
+import { EditorBlock, ObserveCallback } from '../editor-block';
import {
DeleteEditorBlock,
GetEditorBlock,
ReturnEditorBlock,
} from '../editor-block/types';
-import { EditorBlock, ObserveCallback } from '../editor-block';
+import { CommentColumnValue } from '../editor-block/utils/column/types';
+import { DefaultColumnsValue } from './../index';
import {
+ Comment,
CommentReply,
CreateCommentBlock,
CreateReplyBlock,
+ GetCommentsBlock,
UpdateCommentBlock,
UpdateReplyBlock,
- GetCommentsBlock,
- Comment,
} from './types';
-import { DefaultColumnsValue } from './../index';
-import { CommentColumnValue } from '../editor-block/utils/column/types';
-import { WORKSPACE_COMMENTS } from '../../utils';
export class CommentService {
protected editor_block: EditorBlock;
diff --git a/libs/datasource/db-service/src/services/comment/types.ts b/libs/datasource/db-service/src/services/comment/types.ts
index d69206385c..65ac21c519 100644
--- a/libs/datasource/db-service/src/services/comment/types.ts
+++ b/libs/datasource/db-service/src/services/comment/types.ts
@@ -1,4 +1,4 @@
-import { ContentColumnValue, BlockFlavorKeys } from '../index';
+import { BlockFlavorKeys, ContentColumnValue } from '../index';
export interface CommentReply {
id: string;
workspace: string;
diff --git a/libs/datasource/db-service/src/services/database/index.ts b/libs/datasource/db-service/src/services/database/index.ts
index f7b9eb0261..4ea5bbbace 100644
--- a/libs/datasource/db-service/src/services/database/index.ts
+++ b/libs/datasource/db-service/src/services/database/index.ts
@@ -4,14 +4,14 @@ import {
BlockClient,
BlockClientInstance,
BlockContentExporter,
- BlockMatcher,
BlockInitOptions,
+ BlockMatcher,
Connectivity,
} from '@toeverything/datasource/jwt';
import { sleep } from '@toeverything/utils';
-import { ObserverManager, getObserverName } from './observer';
import type { ObserveCallback, ReturnUnobserve } from './observer';
+import { getObserverName, ObserverManager } from './observer';
export type { ObserveCallback, ReturnUnobserve } from './observer';
const workspaces: Record = {};
diff --git a/libs/datasource/db-service/src/services/database/observer.ts b/libs/datasource/db-service/src/services/database/observer.ts
index feabf57d1c..12b64aa39e 100644
--- a/libs/datasource/db-service/src/services/database/observer.ts
+++ b/libs/datasource/db-service/src/services/database/observer.ts
@@ -1,4 +1,4 @@
-import { ChangedStates, BlockImplInstance } from '@toeverything/datasource/jwt';
+import { BlockImplInstance, ChangedStates } from '@toeverything/datasource/jwt';
export type ObserveCallback = (
changeStates: ChangedStates,
diff --git a/libs/datasource/db-service/src/services/editor-block/index.ts b/libs/datasource/db-service/src/services/editor-block/index.ts
index 1bec99a5b9..d24efb9221 100644
--- a/libs/datasource/db-service/src/services/editor-block/index.ts
+++ b/libs/datasource/db-service/src/services/editor-block/index.ts
@@ -1,28 +1,28 @@
-import { diffArrays } from 'diff';
+import { BlockImplInstance, MapOperation } from '@toeverything/datasource/jwt';
import { has } from '@toeverything/utils';
+import { diffArrays } from 'diff';
import { ServiceBaseClass } from '../base';
import type { ReturnUnobserve } from '../database/observer';
+import { Template, TemplateProperties } from './templates/types';
import {
- CreateEditorBlock,
- ReturnEditorBlock,
- GetEditorBlock,
- UpdateEditorBlock,
- DeleteEditorBlock,
AddColumnProps,
- RemoveColumnProps,
- UpdateColumnProps,
BlockFlavorKeys,
+ CreateEditorBlock,
+ DeleteEditorBlock,
+ GetEditorBlock,
+ RemoveColumnProps,
+ ReturnEditorBlock,
+ UpdateColumnProps,
+ UpdateEditorBlock,
} from './types';
import {
- dbBlock2BusinessBlock,
- serializeColumnConfig,
- deserializeColumnConfig,
- getOrInitBlockContentColumnsField,
addColumn,
Column,
+ dbBlock2BusinessBlock,
+ deserializeColumnConfig,
+ getOrInitBlockContentColumnsField,
+ serializeColumnConfig,
} from './utils';
-import { BlockImplInstance, MapOperation } from '@toeverything/datasource/jwt';
-import { TemplateProperties, Template } from './templates/types';
export type ObserveCallback = (businessBlock: ReturnEditorBlock) => void;
export class EditorBlock extends ServiceBaseClass {
async create({
@@ -398,39 +398,38 @@ export class EditorBlock extends ServiceBaseClass {
}
export type {
- CreateEditorBlock,
- ReturnEditorBlock,
- GetEditorBlock,
- UpdateEditorBlock,
- DeleteEditorBlock,
- BlockFlavors,
BlockFlavorKeys,
+ BlockFlavors,
+ CreateEditorBlock,
+ DeleteEditorBlock,
+ GetEditorBlock,
+ ReturnEditorBlock,
+ UpdateEditorBlock,
} from './types';
-
-export type {
- Column,
- ContentColumn,
- NumberColumn,
- EnumColumn,
- DateColumn,
- BooleanColumn,
- FileColumn,
- DefaultColumnsValue,
- ContentColumnValue,
- NumberColumnValue,
- EnumColumnValue,
- BooleanColumnValue,
- DateColumnValue,
- FileColumnValue,
- StringColumnValue,
-} from './utils/column';
export {
ColumnType,
isBooleanColumn,
isContentColumn,
isDateColumn,
+ isEnumColumn,
isFileColumn,
isNumberColumn,
- isEnumColumn,
isStringColumn,
} from './utils/column';
+export type {
+ BooleanColumn,
+ BooleanColumnValue,
+ Column,
+ ContentColumn,
+ ContentColumnValue,
+ DateColumn,
+ DateColumnValue,
+ DefaultColumnsValue,
+ EnumColumn,
+ EnumColumnValue,
+ FileColumn,
+ FileColumnValue,
+ NumberColumn,
+ NumberColumnValue,
+ StringColumnValue,
+} from './utils/column';
diff --git a/libs/datasource/db-service/src/services/editor-block/templates/get-started-group1.json b/libs/datasource/db-service/src/services/editor-block/templates/get-started-group1.json
index b98c0e2fcb..354f85eb46 100644
--- a/libs/datasource/db-service/src/services/editor-block/templates/get-started-group1.json
+++ b/libs/datasource/db-service/src/services/editor-block/templates/get-started-group1.json
@@ -1,83 +1,14 @@
{
"type": "group",
- "properties": {
- "recastCurrentViewId": "vwjI_O0J2CEsHyMW",
- "metaProps": [
- {
- "id": "bNjVwBq8YLxvmvr7",
- "name": "Status#GVsG",
- "type": "status",
- "options": [
- {
- "id": "wusZ8Qht8rsmFD1s",
- "name": "No Started",
- "color": "#AF1212",
- "background": "#FFCECE",
- "iconName": "status"
- },
- {
- "id": "qLJFK5bqYhW8NLtQ",
- "name": "In Progress",
- "color": "#896406",
- "background": "#FFF5AB",
- "iconName": "status"
- },
- {
- "id": "u0ZgY0sRCnqMkxzn",
- "name": "Complete",
- "color": "#05683D",
- "background": "#C5FBE0",
- "iconName": "status"
- }
- ]
- },
- {
- "id": "DfVMd-EXXO9-WZTO",
- "type": "date",
- "name": "Date#0neY",
- "background": "#6880FF",
- "color": "#fff",
- "iconName": "date"
- },
- {
- "id": "UgQQiv9D-72nRyYy",
- "type": "mention",
- "name": "Mention#Recx",
- "background": "#FFD568",
- "color": "#FFFFFF",
- "iconName": "collaborator"
- },
- {
- "id": "ICT1AlKCQkwYLjGs",
- "type": "text",
- "name": "Text#uObM",
- "background": "#67dcaa",
- "color": "#FFF",
- "iconName": "text"
- }
- ],
- "recastViews": [
- {
- "id": "qJslh-HAKnf8gGV-",
- "name": "Text",
- "type": "page"
- },
- {
- "id": "vwjI_O0J2CEsHyMW",
- "name": "Kanban",
- "type": "kanban",
- "groupBy": "bNjVwBq8YLxvmvr7"
- }
- ]
- },
+ "properties": {},
"blocks": [
{
- "type": "text",
+ "type": "heading1",
"properties": {
"text": {
"value": [
{
- "text": "You can customize a Kanban to fit your workflow. Such as by adding/removing columns or changing Tag App labels."
+ "text": "Want to save changes?"
}
]
},
@@ -85,116 +16,41 @@
},
"blocks": []
},
- {
- "type": "text",
- "properties": {
- "text": {
- "value": [{ "text": "Add a Due Date to set a reminder" }]
- },
- "recastValues": {
- "bNjVwBq8YLxvmvr7": {
- "id": "bNjVwBq8YLxvmvr7",
- "type": "status",
- "value": "wusZ8Qht8rsmFD1s"
- },
- "DfVMd-EXXO9-WZTO": {
- "id": "DfVMd-EXXO9-WZTO",
- "type": "date",
- "value": 1660233600000
- }
- },
- "textStyle": {}
- },
- "blocks": []
- },
- {
- "type": "text",
- "properties": {
- "text": {
- "value": [{ "text": "Type @ to mention people" }]
- },
- "recastValues": {
- "bNjVwBq8YLxvmvr7": {
- "id": "bNjVwBq8YLxvmvr7",
- "type": "status",
- "value": "wusZ8Qht8rsmFD1s"
- },
- "UgQQiv9D-72nRyYy": {
- "id": "UgQQiv9D-72nRyYy",
- "type": "mention",
- "value": "AFFiNE"
- }
- },
- "textStyle": {}
- },
- "blocks": []
- },
{
"type": "todo",
"properties": {
"text": {
"value": [
{
- "text": "Check the box to complete the task!"
+ "text": "Your data is always stored locally first, and only stored where you want it."
}
]
- },
- "recastValues": {
- "bNjVwBq8YLxvmvr7": {
- "id": "bNjVwBq8YLxvmvr7",
- "type": "status",
- "value": "qLJFK5bqYhW8NLtQ"
- }
- },
- "textStyle": {},
- "collapsed": { "value": false }
- },
- "blocks": [
- {
- "type": "todo",
- "properties": {
- "text": { "value": [{ "text": "Check 01" }] },
- "textStyle": {},
- "collapsed": { "value": false },
- "checked": { "value": true }
- },
- "blocks": []
- },
- {
- "type": "todo",
- "properties": {
- "text": { "value": [{ "text": "Check 02" }] },
- "textStyle": {}
- },
- "blocks": []
}
- ]
+ }
},
{
- "type": "text",
+ "type": "todo",
"properties": {
"text": {
"value": [
{
- "text": "The GroupBy button allows you to customise how you want your data grouped just utilize your preferred Tag App settings"
+ "text": "So if you want to make changes, you can open a local folder via SYNC TO DISK (you should find the link at the top-right of the page). "
}
]
- },
- "recastValues": {
- "bNjVwBq8YLxvmvr7": {
- "id": "bNjVwBq8YLxvmvr7",
- "type": "status",
- "value": "u0ZgY0sRCnqMkxzn"
- },
- "ICT1AlKCQkwYLjGs": {
- "id": "ICT1AlKCQkwYLjGs",
- "type": "text",
- "value": "GroupBy others"
- }
- },
- "textStyle": {}
- },
- "blocks": []
+ }
+ }
+ },
+ {
+ "type": "todo",
+ "properties": {
+ "text": {
+ "value": [
+ {
+ "text": "Once you have opened a local folder any changes you make will be saved automatically and stored locally on your device only."
+ }
+ ]
+ }
+ }
}
]
}
diff --git a/libs/datasource/db-service/src/services/editor-block/templates/get-started-group2.json b/libs/datasource/db-service/src/services/editor-block/templates/get-started-group2.json
new file mode 100644
index 0000000000..b98c0e2fcb
--- /dev/null
+++ b/libs/datasource/db-service/src/services/editor-block/templates/get-started-group2.json
@@ -0,0 +1,200 @@
+{
+ "type": "group",
+ "properties": {
+ "recastCurrentViewId": "vwjI_O0J2CEsHyMW",
+ "metaProps": [
+ {
+ "id": "bNjVwBq8YLxvmvr7",
+ "name": "Status#GVsG",
+ "type": "status",
+ "options": [
+ {
+ "id": "wusZ8Qht8rsmFD1s",
+ "name": "No Started",
+ "color": "#AF1212",
+ "background": "#FFCECE",
+ "iconName": "status"
+ },
+ {
+ "id": "qLJFK5bqYhW8NLtQ",
+ "name": "In Progress",
+ "color": "#896406",
+ "background": "#FFF5AB",
+ "iconName": "status"
+ },
+ {
+ "id": "u0ZgY0sRCnqMkxzn",
+ "name": "Complete",
+ "color": "#05683D",
+ "background": "#C5FBE0",
+ "iconName": "status"
+ }
+ ]
+ },
+ {
+ "id": "DfVMd-EXXO9-WZTO",
+ "type": "date",
+ "name": "Date#0neY",
+ "background": "#6880FF",
+ "color": "#fff",
+ "iconName": "date"
+ },
+ {
+ "id": "UgQQiv9D-72nRyYy",
+ "type": "mention",
+ "name": "Mention#Recx",
+ "background": "#FFD568",
+ "color": "#FFFFFF",
+ "iconName": "collaborator"
+ },
+ {
+ "id": "ICT1AlKCQkwYLjGs",
+ "type": "text",
+ "name": "Text#uObM",
+ "background": "#67dcaa",
+ "color": "#FFF",
+ "iconName": "text"
+ }
+ ],
+ "recastViews": [
+ {
+ "id": "qJslh-HAKnf8gGV-",
+ "name": "Text",
+ "type": "page"
+ },
+ {
+ "id": "vwjI_O0J2CEsHyMW",
+ "name": "Kanban",
+ "type": "kanban",
+ "groupBy": "bNjVwBq8YLxvmvr7"
+ }
+ ]
+ },
+ "blocks": [
+ {
+ "type": "text",
+ "properties": {
+ "text": {
+ "value": [
+ {
+ "text": "You can customize a Kanban to fit your workflow. Such as by adding/removing columns or changing Tag App labels."
+ }
+ ]
+ },
+ "textStyle": {}
+ },
+ "blocks": []
+ },
+ {
+ "type": "text",
+ "properties": {
+ "text": {
+ "value": [{ "text": "Add a Due Date to set a reminder" }]
+ },
+ "recastValues": {
+ "bNjVwBq8YLxvmvr7": {
+ "id": "bNjVwBq8YLxvmvr7",
+ "type": "status",
+ "value": "wusZ8Qht8rsmFD1s"
+ },
+ "DfVMd-EXXO9-WZTO": {
+ "id": "DfVMd-EXXO9-WZTO",
+ "type": "date",
+ "value": 1660233600000
+ }
+ },
+ "textStyle": {}
+ },
+ "blocks": []
+ },
+ {
+ "type": "text",
+ "properties": {
+ "text": {
+ "value": [{ "text": "Type @ to mention people" }]
+ },
+ "recastValues": {
+ "bNjVwBq8YLxvmvr7": {
+ "id": "bNjVwBq8YLxvmvr7",
+ "type": "status",
+ "value": "wusZ8Qht8rsmFD1s"
+ },
+ "UgQQiv9D-72nRyYy": {
+ "id": "UgQQiv9D-72nRyYy",
+ "type": "mention",
+ "value": "AFFiNE"
+ }
+ },
+ "textStyle": {}
+ },
+ "blocks": []
+ },
+ {
+ "type": "todo",
+ "properties": {
+ "text": {
+ "value": [
+ {
+ "text": "Check the box to complete the task!"
+ }
+ ]
+ },
+ "recastValues": {
+ "bNjVwBq8YLxvmvr7": {
+ "id": "bNjVwBq8YLxvmvr7",
+ "type": "status",
+ "value": "qLJFK5bqYhW8NLtQ"
+ }
+ },
+ "textStyle": {},
+ "collapsed": { "value": false }
+ },
+ "blocks": [
+ {
+ "type": "todo",
+ "properties": {
+ "text": { "value": [{ "text": "Check 01" }] },
+ "textStyle": {},
+ "collapsed": { "value": false },
+ "checked": { "value": true }
+ },
+ "blocks": []
+ },
+ {
+ "type": "todo",
+ "properties": {
+ "text": { "value": [{ "text": "Check 02" }] },
+ "textStyle": {}
+ },
+ "blocks": []
+ }
+ ]
+ },
+ {
+ "type": "text",
+ "properties": {
+ "text": {
+ "value": [
+ {
+ "text": "The GroupBy button allows you to customise how you want your data grouped just utilize your preferred Tag App settings"
+ }
+ ]
+ },
+ "recastValues": {
+ "bNjVwBq8YLxvmvr7": {
+ "id": "bNjVwBq8YLxvmvr7",
+ "type": "status",
+ "value": "u0ZgY0sRCnqMkxzn"
+ },
+ "ICT1AlKCQkwYLjGs": {
+ "id": "ICT1AlKCQkwYLjGs",
+ "type": "text",
+ "value": "GroupBy others"
+ }
+ },
+ "textStyle": {}
+ },
+ "blocks": []
+ }
+ ]
+}
diff --git a/libs/datasource/db-service/src/services/editor-block/templates/index.ts b/libs/datasource/db-service/src/services/editor-block/templates/index.ts
index a4e0e82300..61b236ff3b 100644
--- a/libs/datasource/db-service/src/services/editor-block/templates/index.ts
+++ b/libs/datasource/db-service/src/services/editor-block/templates/index.ts
@@ -1,3 +1,2 @@
export { TemplateFactory } from './template-factory';
-
export * from './types';
diff --git a/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts b/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts
index 10af0eebb9..6c8d5a5643 100644
--- a/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts
+++ b/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts
@@ -1,10 +1,11 @@
-import { Template, TemplateMeta, GroupTemplate } from './types';
import blogTemplate from './blog.json';
import emptyTemplate from './empty.json';
-import gridTemplate from './grid.json';
-import todoTemplate from './todo.json';
import getStartedGroup0 from './get-started-group0.json';
import getStartedGroup1 from './get-started-group1.json';
+import getStartedGroup2 from './get-started-group2.json';
+import gridTemplate from './grid.json';
+import todoTemplate from './todo.json';
+import { Template, TemplateMeta } from './types';
export type GroupTemplateKeys =
| 'todolist'
@@ -12,7 +13,8 @@ export type GroupTemplateKeys =
| 'empty'
| 'grid'
| 'getStartedGroup0'
- | 'getStartedGroup1';
+ | 'getStartedGroup1'
+ | 'getStartedGroup2';
type GroupTemplateMap = Record;
const groupTemplateMap = {
empty: emptyTemplate,
@@ -21,6 +23,7 @@ const groupTemplateMap = {
grid: gridTemplate,
getStartedGroup0,
getStartedGroup1,
+ getStartedGroup2,
} as GroupTemplateMap;
const defaultTemplateList: Array = [
diff --git a/libs/datasource/db-service/src/services/editor-block/utils/column/default-config.ts b/libs/datasource/db-service/src/services/editor-block/utils/column/default-config.ts
index 2577c94ce4..ca51be0f8c 100644
--- a/libs/datasource/db-service/src/services/editor-block/utils/column/default-config.ts
+++ b/libs/datasource/db-service/src/services/editor-block/utils/column/default-config.ts
@@ -1,22 +1,21 @@
import {
+ BooleanColumnValue,
Column,
ColumnType,
+ CommentColumnValue,
ContentColumnValue,
- BooleanColumnValue,
- StringColumnValue,
- FileColumnValue,
DateColumnValue,
EnumColumnValue,
- CommentColumnValue,
+ FileColumnValue,
FilterConstraint,
SorterConstraint,
+ StringColumnValue,
} from './types';
export enum GroupScene {
page = 'page',
table = 'table',
kanban = 'kanban',
- whiteboard = 'whiteboard',
}
/**
@@ -54,6 +53,7 @@ export type DefaultColumnsValue = {
filterConstraint: FilterConstraint;
filterWeakSqlConstraint: string;
sorterConstraint: SorterConstraint;
+ bindings: StringColumnValue;
};
export const DEFAULT_COLUMN_KEYS = {
diff --git a/libs/datasource/db-service/src/services/editor-block/utils/column/index.ts b/libs/datasource/db-service/src/services/editor-block/utils/column/index.ts
index 25809f8b06..8f469a591c 100644
--- a/libs/datasource/db-service/src/services/editor-block/utils/column/index.ts
+++ b/libs/datasource/db-service/src/services/editor-block/utils/column/index.ts
@@ -1,11 +1,11 @@
-import { nanoid } from 'nanoid';
import {
+ ArrayOperation,
BlockImplInstance,
MapOperation,
- ArrayOperation,
} from '@toeverything/datasource/jwt';
-import type { Column } from './types';
+import { nanoid } from 'nanoid';
import { DEFAULT_COLUMNS } from './default-config';
+import type { Column } from './types';
export const serializeColumnConfig = (column: Column): string => {
// TODO: Do the type check of the column parameter here
return JSON.stringify(column);
@@ -87,31 +87,30 @@ export const getBlockColumns = (
return columns;
};
+export type { DefaultColumnsValue } from './default-config';
+export { ColumnType } from './types';
export type {
+ BooleanColumn,
+ BooleanColumnValue,
Column,
ContentColumn,
- NumberColumn,
- EnumColumn,
- DateColumn,
- BooleanColumn,
- FileColumn,
ContentColumnValue,
- NumberColumnValue,
- EnumColumnValue,
- BooleanColumnValue,
+ DateColumn,
DateColumnValue,
+ EnumColumn,
+ EnumColumnValue,
+ FileColumn,
FileColumnValue,
+ NumberColumn,
+ NumberColumnValue,
StringColumnValue,
} from './types';
-export { ColumnType } from './types';
-export type { DefaultColumnsValue } from './default-config';
-
export {
+ isBooleanColumn,
isContentColumn,
isDateColumn,
+ isEnumColumn,
isFileColumn,
isNumberColumn,
- isEnumColumn,
isStringColumn,
- isBooleanColumn,
} from './utils';
diff --git a/libs/datasource/db-service/src/services/editor-block/utils/column/types.ts b/libs/datasource/db-service/src/services/editor-block/utils/column/types.ts
index d5c15ebaac..241400d8e3 100644
--- a/libs/datasource/db-service/src/services/editor-block/utils/column/types.ts
+++ b/libs/datasource/db-service/src/services/editor-block/utils/column/types.ts
@@ -1,5 +1,4 @@
/** Column */
-import type { CSSProperties } from 'react';
export enum ColumnType {
/**
diff --git a/libs/datasource/db-service/src/services/editor-block/utils/column/utils.ts b/libs/datasource/db-service/src/services/editor-block/utils/column/utils.ts
index 77822235a4..96e8639c15 100644
--- a/libs/datasource/db-service/src/services/editor-block/utils/column/utils.ts
+++ b/libs/datasource/db-service/src/services/editor-block/utils/column/utils.ts
@@ -1,12 +1,12 @@
import type {
+ BooleanColumn,
Column,
ContentColumn,
- StringColumn,
- NumberColumn,
- EnumColumn,
DateColumn,
+ EnumColumn,
FileColumn,
- BooleanColumn,
+ NumberColumn,
+ StringColumn,
} from './types';
export const isContentColumn = (column: Column): column is ContentColumn => {
diff --git a/libs/datasource/db-service/src/services/editor-block/utils/index.ts b/libs/datasource/db-service/src/services/editor-block/utils/index.ts
index 400c592148..b9a6f5efa5 100644
--- a/libs/datasource/db-service/src/services/editor-block/utils/index.ts
+++ b/libs/datasource/db-service/src/services/editor-block/utils/index.ts
@@ -1,7 +1,7 @@
import type { BlockImplInstance } from '@toeverything/datasource/jwt';
import { ReturnEditorBlock } from '../types';
-import { getClosestGroup } from './common';
import { getBlockColumns } from './column';
+import { getClosestGroup } from './common';
interface DbBlock2BusinessBlockProps {
workspace: string;
@@ -31,27 +31,27 @@ export const dbBlock2BusinessBlock = ({
};
export {
- getOrInitBlockContentColumnsField,
- serializeColumnConfig,
- deserializeColumnConfig,
addColumn,
ColumnType,
+ deserializeColumnConfig,
+ getOrInitBlockContentColumnsField,
isBooleanColumn,
isContentColumn,
isDateColumn,
+ isEnumColumn,
isFileColumn,
isNumberColumn,
- isEnumColumn,
isStringColumn,
+ serializeColumnConfig,
} from './column';
export type {
- Column,
- DefaultColumnsValue,
- ContentColumnValue,
- NumberColumnValue,
- EnumColumnValue,
BooleanColumnValue,
+ Column,
+ ContentColumnValue,
DateColumnValue,
+ DefaultColumnsValue,
+ EnumColumnValue,
FileColumnValue,
+ NumberColumnValue,
StringColumnValue,
} from './column';
diff --git a/libs/datasource/db-service/src/services/index.ts b/libs/datasource/db-service/src/services/index.ts
index 827f90ebea..315ee84496 100644
--- a/libs/datasource/db-service/src/services/index.ts
+++ b/libs/datasource/db-service/src/services/index.ts
@@ -1,46 +1,46 @@
-import { DiContainer } from '@toeverything/utils';
import type { RegisterDependencyConfig } from '@toeverything/utils';
+import { DiContainer } from '@toeverything/utils';
+import { CommentService } from './comment';
import { Database } from './database';
-import { PageTree } from './workspace/page-tree';
-import { UserConfig } from './workspace/user-config';
import { EditorBlock } from './editor-block';
import { FileService } from './file';
-import { CommentService } from './comment';
+import { PageTree } from './workspace/page-tree';
+import { UserConfig } from './workspace/user-config';
-export type {
- CreateEditorBlock,
- ReturnEditorBlock,
- GetEditorBlock,
- DeleteEditorBlock,
- UpdateEditorBlock,
- BlockFlavors,
- BlockFlavorKeys,
- Column,
- ContentColumn,
- NumberColumn,
- EnumColumn,
- DateColumn,
- BooleanColumn,
- FileColumn,
- DefaultColumnsValue,
- ContentColumnValue,
- NumberColumnValue,
- EnumColumnValue,
- BooleanColumnValue,
- DateColumnValue,
- FileColumnValue,
- StringColumnValue,
-} from './editor-block';
export {
ColumnType,
isBooleanColumn,
isContentColumn,
isDateColumn,
+ isEnumColumn,
isFileColumn,
isNumberColumn,
- isEnumColumn,
isStringColumn,
} from './editor-block';
+export type {
+ BlockFlavorKeys,
+ BlockFlavors,
+ BooleanColumn,
+ BooleanColumnValue,
+ Column,
+ ContentColumn,
+ ContentColumnValue,
+ CreateEditorBlock,
+ DateColumn,
+ DateColumnValue,
+ DefaultColumnsValue,
+ DeleteEditorBlock,
+ EnumColumn,
+ EnumColumnValue,
+ FileColumn,
+ FileColumnValue,
+ GetEditorBlock,
+ NumberColumn,
+ NumberColumnValue,
+ ReturnEditorBlock,
+ StringColumnValue,
+ UpdateEditorBlock,
+} from './editor-block';
export interface DbServicesMap {
editorBlock: EditorBlock;
diff --git a/libs/datasource/db-service/src/services/workspace/page-tree.ts b/libs/datasource/db-service/src/services/workspace/page-tree.ts
index 9b4a348c2f..51d4f23c8c 100644
--- a/libs/datasource/db-service/src/services/workspace/page-tree.ts
+++ b/libs/datasource/db-service/src/services/workspace/page-tree.ts
@@ -1,7 +1,7 @@
import type { BlockClientInstance } from '@toeverything/datasource/jwt';
import { PAGE_TREE as pageTreeName } from '../../utils';
-import type { ReturnUnobserve } from '../database/observer';
import { ServiceBaseClass } from '../base';
+import type { ReturnUnobserve } from '../database/observer';
import { TreeItem } from './types';
export type ObserveCallback = () => void;
diff --git a/libs/datasource/db-service/src/services/workspace/user-config.ts b/libs/datasource/db-service/src/services/workspace/user-config.ts
index 277c3473c7..5a52581c21 100644
--- a/libs/datasource/db-service/src/services/workspace/user-config.ts
+++ b/libs/datasource/db-service/src/services/workspace/user-config.ts
@@ -1,9 +1,9 @@
+import type { QueryIndexMetadata } from '@toeverything/datasource/jwt';
import { RECENT_PAGES, WORKSPACE_CONFIG } from '../../utils';
import { ServiceBaseClass } from '../base';
import { ObserveCallback, ReturnUnobserve } from '../database';
import { PageTree } from './page-tree';
import { PageConfigItem } from './types';
-import type { QueryIndexMetadata } from '@toeverything/datasource/jwt';
/** Operate the user configuration at the workspace level */
export class UserConfig extends ServiceBaseClass {
diff --git a/libs/datasource/jwt-rpc/src/broadcast.ts b/libs/datasource/jwt-rpc/src/broadcast.ts
index ed5dfd2ebc..b0f344aad7 100644
--- a/libs/datasource/jwt-rpc/src/broadcast.ts
+++ b/libs/datasource/jwt-rpc/src/broadcast.ts
@@ -1,8 +1,8 @@
-import * as Y from 'yjs';
import * as bc from 'lib0/broadcastchannel';
import * as encoding from 'lib0/encoding';
-import * as syncProtocol from 'y-protocols/sync';
import * as awarenessProtocol from 'y-protocols/awareness';
+import * as syncProtocol from 'y-protocols/sync';
+import * as Y from 'yjs';
import { Message } from './handler';
import { readMessage } from './processor';
diff --git a/libs/datasource/jwt-rpc/src/handler.ts b/libs/datasource/jwt-rpc/src/handler.ts
index 4bfd5a20f0..e803fb4bab 100644
--- a/libs/datasource/jwt-rpc/src/handler.ts
+++ b/libs/datasource/jwt-rpc/src/handler.ts
@@ -1,5 +1,5 @@
-import * as encoding from 'lib0/encoding';
import * as decoding from 'lib0/decoding';
+import * as encoding from 'lib0/encoding';
import * as authProtocol from 'y-protocols/auth';
import * as awarenessProtocol from 'y-protocols/awareness';
import * as syncProtocol from 'y-protocols/sync';
diff --git a/libs/datasource/jwt-rpc/src/indexeddb.ts b/libs/datasource/jwt-rpc/src/indexeddb.ts
index 512daea6d4..fbaaab1ac8 100644
--- a/libs/datasource/jwt-rpc/src/indexeddb.ts
+++ b/libs/datasource/jwt-rpc/src/indexeddb.ts
@@ -1,7 +1,7 @@
-import * as Y from 'yjs';
import * as idb from 'lib0/indexeddb.js';
import * as mutex from 'lib0/mutex.js';
import { Observable } from 'lib0/observable.js';
+import * as Y from 'yjs';
const customStoreName = 'custom';
const updatesStoreName = 'updates';
diff --git a/libs/datasource/jwt-rpc/src/processor.ts b/libs/datasource/jwt-rpc/src/processor.ts
index 4270fdf8dd..c7097156b8 100644
--- a/libs/datasource/jwt-rpc/src/processor.ts
+++ b/libs/datasource/jwt-rpc/src/processor.ts
@@ -1,8 +1,8 @@
-import * as Y from 'yjs';
-import * as encoding from 'lib0/encoding';
import * as decoding from 'lib0/decoding';
-import * as syncProtocol from 'y-protocols/sync';
+import * as encoding from 'lib0/encoding';
import * as awarenessProtocol from 'y-protocols/awareness';
+import * as syncProtocol from 'y-protocols/sync';
+import * as Y from 'yjs';
import { Message } from './handler';
import { WebsocketProvider } from './provider';
diff --git a/libs/datasource/jwt-rpc/src/provider.ts b/libs/datasource/jwt-rpc/src/provider.ts
index 86a59b14c3..0ce7f6a1b3 100644
--- a/libs/datasource/jwt-rpc/src/provider.ts
+++ b/libs/datasource/jwt-rpc/src/provider.ts
@@ -6,9 +6,8 @@ import * as url from 'lib0/url';
import * as awarenessProtocol from 'y-protocols/awareness';
import { handler } from './handler';
-import { registerBroadcastSubscriber } from './broadcast';
-import { registerWebsocket } from './websocket';
import { registerUpdateHandler } from './processor';
+import { registerWebsocket } from './websocket';
/**
* Websocket Provider for Yjs. Creates a websocket connection to sync the shared document.
diff --git a/libs/datasource/jwt-rpc/src/sqlite.ts b/libs/datasource/jwt-rpc/src/sqlite.ts
index 1753edda8b..f88a59247f 100644
--- a/libs/datasource/jwt-rpc/src/sqlite.ts
+++ b/libs/datasource/jwt-rpc/src/sqlite.ts
@@ -1,6 +1,6 @@
-import * as Y from 'yjs';
-import sqlite, { Database, SqlJsStatic } from 'sql.js';
import { Observable } from 'lib0/observable.js';
+import sqlite, { Database, SqlJsStatic } from 'sql.js';
+import * as Y from 'yjs';
const PREFERRED_TRIM_SIZE = 500;
diff --git a/libs/datasource/jwt-rpc/src/websocket.ts b/libs/datasource/jwt-rpc/src/websocket.ts
index fa43db554b..4395cf5d53 100644
--- a/libs/datasource/jwt-rpc/src/websocket.ts
+++ b/libs/datasource/jwt-rpc/src/websocket.ts
@@ -1,8 +1,8 @@
-import * as time from 'lib0/time';
import * as encoding from 'lib0/encoding';
-import * as syncProtocol from 'y-protocols/sync';
-import * as awarenessProtocol from 'y-protocols/awareness';
import * as math from 'lib0/math';
+import * as time from 'lib0/time';
+import * as awarenessProtocol from 'y-protocols/awareness';
+import * as syncProtocol from 'y-protocols/sync';
import { Message } from './handler';
import { readMessage } from './processor';
diff --git a/libs/datasource/jwt/src/adapter/index.ts b/libs/datasource/jwt/src/adapter/index.ts
index 2fa2ec551d..2d7176e6be 100644
--- a/libs/datasource/jwt/src/adapter/index.ts
+++ b/libs/datasource/jwt/src/adapter/index.ts
@@ -184,11 +184,11 @@ export const getDataExporter = () => {
return { importData, exportData, hasExporter, installExporter };
};
+export { YjsAdapter } from './yjs';
+export type { YjsContentOperation, YjsInitOptions } from './yjs';
export type {
AsyncDatabaseAdapter,
BlockPosition,
BlockInstance,
ContentOperation,
};
-export type { YjsInitOptions, YjsContentOperation } from './yjs';
-export { YjsAdapter } from './yjs';
diff --git a/libs/datasource/jwt/src/adapter/yjs/block.ts b/libs/datasource/jwt/src/adapter/yjs/block.ts
index 1f49ad0ed1..3f2b756799 100644
--- a/libs/datasource/jwt/src/adapter/yjs/block.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/block.ts
@@ -5,12 +5,12 @@ import {
transact,
} from 'yjs';
-import { BlockInstance, BlockListener, HistoryManager } from '../index';
import { BlockItem, BlockTypes } from '../../types';
+import { BlockInstance, BlockListener, HistoryManager } from '../index';
-import { YjsContentOperation } from './operation';
-import { ChildrenListenerHandler, ContentListenerHandler } from './listener';
import { YjsHistoryManager } from './history';
+import { ChildrenListenerHandler, ContentListenerHandler } from './listener';
+import { YjsContentOperation } from './operation';
const GET_BLOCK_ITEM = Symbol('GET_BLOCK_ITEM');
diff --git a/libs/datasource/jwt/src/adapter/yjs/index.ts b/libs/datasource/jwt/src/adapter/yjs/index.ts
index 77f1ac4902..ec201c2d84 100644
--- a/libs/datasource/jwt/src/adapter/yjs/index.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/index.ts
@@ -5,17 +5,17 @@ import { Buffer } from 'buffer';
import { saveAs } from 'file-saver';
import { fromEvent } from 'file-selector';
import LRUCache from 'lru-cache';
-import { debounce } from 'ts-debounce';
import { nanoid } from 'nanoid';
+import { debounce } from 'ts-debounce';
import { Awareness } from 'y-protocols/awareness.js';
import {
- Doc,
- Array as YArray,
- Map as YMap,
- transact,
- encodeStateAsUpdate,
applyUpdate,
+ Array as YArray,
+ Doc,
+ encodeStateAsUpdate,
+ Map as YMap,
snapshot,
+ transact,
} from 'yjs';
import {
@@ -31,12 +31,12 @@ import { getLogger, sha3, sleep } from '../../utils';
import { YjsRemoteBinaries } from './binary';
import { YjsBlockInstance } from './block';
import { GateKeeper } from './gatekeeper';
-import {
- YjsContentOperation,
- DO_NOT_USE_THIS_OR_YOU_WILL_BE_FIRED_SYMBOL_INTO_INNER as INTO_INNER,
-} from './operation';
-import { EmitEvents, Suspend } from './listener';
import { YjsHistoryManager } from './history';
+import { EmitEvents, Suspend } from './listener';
+import {
+ DO_NOT_USE_THIS_OR_YOU_WILL_BE_FIRED_SYMBOL_INTO_INNER as INTO_INNER,
+ YjsContentOperation,
+} from './operation';
import { YjsProvider } from './provider';
declare const JWT_DEV: boolean;
@@ -78,7 +78,7 @@ async function _initYjsDatabase(
await _waitLoading(workspace);
}
const instance = _yjsDatabaseInstance.get(workspace);
- // tTODO:odo temporarily handle this
+ // TODO: temporarily handle this
if (
instance &&
(instance.userId === options.userId || options.userId === 'default')
@@ -110,7 +110,7 @@ async function _initYjsDatabase(
const emitState = (c: Connectivity) =>
connListener.listeners?.(workspace, c);
await Promise.all(
- Object.entries(options.provider).flatMap(async ([, p]) => [
+ Object.entries(options.provider).flatMap(([, p]) => [
p({ awareness, doc, token, workspace, emitState }),
p({
awareness,
@@ -142,6 +142,8 @@ async function _initYjsDatabase(
export type { YjsBlockInstance } from './block';
export type { YjsContentOperation } from './operation';
+export { getYjsProviders } from './provider';
+export type { YjsProviderOptions } from './provider';
export type YjsInitOptions = {
userId?: string;
@@ -149,9 +151,6 @@ export type YjsInitOptions = {
provider?: Record;
};
-export { getYjsProviders } from './provider';
-export type { YjsProviderOptions } from './provider';
-
export class YjsAdapter implements AsyncDatabaseAdapter {
private readonly _provider: YjsProviders;
private readonly _doc: Doc; // doc instance
diff --git a/libs/datasource/jwt/src/adapter/yjs/provider.ts b/libs/datasource/jwt/src/adapter/yjs/provider.ts
index e4cebd1f01..ba1835cc52 100644
--- a/libs/datasource/jwt/src/adapter/yjs/provider.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/provider.ts
@@ -1,5 +1,5 @@
-import { Doc } from 'yjs';
import { Awareness } from 'y-protocols/awareness.js';
+import { Doc } from 'yjs';
import {
IndexedDBProvider,
diff --git a/libs/datasource/jwt/src/block/abstract.ts b/libs/datasource/jwt/src/block/abstract.ts
index 468fd53321..38ee415e05 100644
--- a/libs/datasource/jwt/src/block/abstract.ts
+++ b/libs/datasource/jwt/src/block/abstract.ts
@@ -8,10 +8,10 @@ import {
MapOperation,
} from '../adapter';
import {
- BlockTypes,
- BlockTypeKeys,
- BlockFlavors,
BlockFlavorKeys,
+ BlockFlavors,
+ BlockTypeKeys,
+ BlockTypes,
} from '../types';
import { getLogger } from '../utils';
diff --git a/libs/datasource/jwt/src/block/index.ts b/libs/datasource/jwt/src/block/index.ts
index a23b29fb14..4d9322c38d 100644
--- a/libs/datasource/jwt/src/block/index.ts
+++ b/libs/datasource/jwt/src/block/index.ts
@@ -8,5 +8,5 @@ export type BlockSearchItem = Partial<
export { BaseBlock } from './base';
export type { Decoration, ReadableContentExporter } from './base';
-export { BlockIndexer } from './indexer';
export type { BlockCapability } from './capability';
+export { BlockIndexer } from './indexer';
diff --git a/libs/datasource/jwt/src/block/indexer.ts b/libs/datasource/jwt/src/block/indexer.ts
index d9ecde1658..dfee685b7e 100644
--- a/libs/datasource/jwt/src/block/indexer.ts
+++ b/libs/datasource/jwt/src/block/indexer.ts
@@ -1,8 +1,8 @@
/* eslint-disable max-lines */
import { createNewSortInstance } from 'fast-sort';
-import { deflateSync, inflateSync, strToU8, strFromU8 } from 'fflate';
+import { deflateSync, inflateSync, strFromU8, strToU8 } from 'fflate';
import { Document as DocumentIndexer, DocumentSearchOptions } from 'flexsearch';
-import { get, set, keys, del, createStore } from 'idb-keyval';
+import { createStore, del, get, keys, set } from 'idb-keyval';
import produce from 'immer';
import LRUCache from 'lru-cache';
import sift, { Query } from 'sift';
diff --git a/libs/datasource/jwt/src/index.ts b/libs/datasource/jwt/src/index.ts
index 38bc11396e..664e0f21fa 100644
--- a/libs/datasource/jwt/src/index.ts
+++ b/libs/datasource/jwt/src/index.ts
@@ -1,21 +1,20 @@
/* eslint-disable max-lines */
import { DocumentSearchOptions } from 'flexsearch';
import LRUCache from 'lru-cache';
-
import {
AsyncDatabaseAdapter,
- YjsAdapter,
- YjsInitOptions,
- YjsContentOperation,
- ChangedStates,
- BlockListener,
BlockInstance,
- ContentOperation,
- HistoryManager,
- ContentTypes,
+ BlockListener,
+ ChangedStates,
Connectivity,
+ ContentOperation,
+ ContentTypes,
DataExporter,
getDataExporter,
+ HistoryManager,
+ YjsAdapter,
+ YjsContentOperation,
+ YjsInitOptions,
} from './adapter';
import {
getYjsProviders,
@@ -30,14 +29,14 @@ import {
} from './block';
import { QueryIndexMetadata } from './block/indexer';
import {
- BlockTypes,
- BlockTypeKeys,
- BlockFlavors,
- UUID,
BlockFlavorKeys,
+ BlockFlavors,
BlockItem,
- ExcludeFunction,
+ BlockTypeKeys,
+ BlockTypes,
BucketBackend,
+ ExcludeFunction,
+ UUID,
} from './types';
import { BlockEventBus, genUUID, getLogger } from './utils';
@@ -290,19 +289,22 @@ export class BlockClient<
| string
| Partial>
): Promise {
- const promised_pages = await Promise.all(
- this.search(part_of_title_or_content).flatMap(({ result }) =>
- result.map(async id => {
- const page = this._pageMapping.get(id as string);
- if (page) return page;
- const block = await this.get(id as BlockTypeKeys);
- return this.set_page(block);
- })
- )
- );
- const pages = [
- ...new Set(promised_pages.filter((v): v is string => !!v)),
- ];
+ let pages = [];
+ if (part_of_title_or_content) {
+ const promisedPages = await Promise.all(
+ this.search(part_of_title_or_content).flatMap(({ result }) =>
+ result.map(async id => {
+ const page = this._pageMapping.get(id as string);
+ if (page) return page;
+ const block = await this.get(id as BlockTypeKeys);
+ return this.set_page(block);
+ })
+ )
+ );
+ pages = [...new Set(promisedPages.filter((v): v is string => !!v))];
+ } else {
+ pages = await this.getBlockByFlavor('page');
+ }
return Promise.all(
this._blockIndexer.getMetadata(pages).map(async page => ({
content: this.get_decoded_content(
@@ -649,18 +651,18 @@ export type BlockInitOptions = NonNullable<
>;
export type {
- TextOperation,
ArrayOperation,
- MapOperation,
ChangedStates,
Connectivity,
+ MapOperation,
+ TextOperation,
} from './adapter';
export type {
BlockSearchItem,
Decoration as BlockDecoration,
ReadableContentExporter as BlockContentExporter,
} from './block';
-export type { BlockTypeKeys } from './types';
export { BlockTypes, BucketBackend as BlockBackend } from './types';
+export type { BlockTypeKeys } from './types';
export { isBlock } from './utils';
export type { QueryIndexMetadata };
diff --git a/libs/datasource/jwt/src/types/block.ts b/libs/datasource/jwt/src/types/block.ts
index cd0300e5a1..3b04dc7830 100644
--- a/libs/datasource/jwt/src/types/block.ts
+++ b/libs/datasource/jwt/src/types/block.ts
@@ -37,7 +37,6 @@ export const BlockFlavors = {
quote: 'quote' as const, // quote
toc: 'toc' as const, //directory
database: 'database' as const, //Multidimensional table
- whiteboard: 'whiteboard' as const, // whiteboard
template: 'template' as const, // template
discussion: 'discussion' as const, // comment header
comment: 'comment' as const, // comment details
diff --git a/libs/datasource/jwt/src/types/index.ts b/libs/datasource/jwt/src/types/index.ts
index d23b301f36..a205f2a685 100644
--- a/libs/datasource/jwt/src/types/index.ts
+++ b/libs/datasource/jwt/src/types/index.ts
@@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/naming-convention */
-export { BlockTypes, BlockFlavors } from './block';
-export type { BlockTypeKeys, BlockFlavorKeys, BlockItem } from './block';
-export type { UUID } from './uuid';
+export { BlockFlavors, BlockTypes } from './block';
+export type { BlockFlavorKeys, BlockItem, BlockTypeKeys } from './block';
export type { ExcludeFunction } from './utils';
+export type { UUID } from './uuid';
function getLocation() {
try {
diff --git a/libs/datasource/remote-kv/src/aws/aws-attachment.ts b/libs/datasource/remote-kv/src/aws/aws-attachment.ts
index ee13dc771b..a9eac2861a 100644
--- a/libs/datasource/remote-kv/src/aws/aws-attachment.ts
+++ b/libs/datasource/remote-kv/src/aws/aws-attachment.ts
@@ -1,8 +1,10 @@
-import * as AWS from 'aws-sdk';
import type { Credentials } from 'aws-sdk';
+import * as AWS from 'aws-sdk';
import type { ManagedUpload } from 'aws-sdk/lib/s3/managed_upload';
import { saveAs } from 'file-saver';
+import { MESSAGE_INFO } from '../constant/message-info';
+import toAsync from '../utils/to-async';
import {
bucketName,
bucketRegion,
@@ -10,8 +12,6 @@ import {
identityPoolId,
keyCreator,
} from './aws-config';
-import toAsync from '../utils/to-async';
-import { MESSAGE_INFO } from '../constant/message-info';
export default class AwsAttachment {
readonly #s3;
diff --git a/libs/datasource/state/src/index.ts b/libs/datasource/state/src/index.ts
index 19ee32136b..fbd263f5d7 100644
--- a/libs/datasource/state/src/index.ts
+++ b/libs/datasource/state/src/index.ts
@@ -1,3 +1,3 @@
+export * from './page';
export * from './ui';
export * from './user';
-export * from './page';
diff --git a/libs/datasource/state/src/page.ts b/libs/datasource/state/src/page.ts
index b296d2824e..093ee78398 100644
--- a/libs/datasource/state/src/page.ts
+++ b/libs/datasource/state/src/page.ts
@@ -1,6 +1,6 @@
-import { useCallback, useEffect } from 'react';
-import { useParams, useLocation } from 'react-router-dom';
import { atom, useAtom } from 'jotai';
+import { useEffect } from 'react';
+import { useLocation, useParams } from 'react-router-dom';
// import { Virgo } from '@toeverything/components/editor-core';
// type EditorsMap = Record;
diff --git a/libs/datasource/state/src/ui.ts b/libs/datasource/state/src/ui.ts
index a47c0498db..90844d39c6 100644
--- a/libs/datasource/state/src/ui.ts
+++ b/libs/datasource/state/src/ui.ts
@@ -1,5 +1,5 @@
-import { useCallback } from 'react';
import { atom, useAtom } from 'jotai';
+import { useCallback } from 'react';
const _showSpaceSidebarAtom = atom(true);
const _fixedDisplayAtom = atom(true);
diff --git a/libs/datasource/state/src/user.ts b/libs/datasource/state/src/user.ts
index d32fef2c56..61893471de 100644
--- a/libs/datasource/state/src/user.ts
+++ b/libs/datasource/state/src/user.ts
@@ -1,4 +1,3 @@
-import { useNavigate } from 'react-router';
import {
getAuth,
onAuthStateChanged,
@@ -6,6 +5,7 @@ import {
} from 'firebase/auth';
import { atom, useAtom } from 'jotai';
import { useEffect, useMemo } from 'react';
+import { useLocation, useNavigate } from 'react-router';
import { useIdentifyUser } from '@toeverything/datasource/feature-flags';
import { UserInfo } from '@toeverything/utils';
@@ -63,6 +63,7 @@ const BRAND_ID = 'AFFiNE';
const _localTrigger = atom(false);
const _useUserAndSpacesForFreeLogin = () => {
+ const location = useLocation();
const navigate = useNavigate();
const [user, setUser] = useAtom(_userAtom);
const [loading, setLoading] = useAtom(_loadingAtom);
@@ -70,7 +71,11 @@ const _useUserAndSpacesForFreeLogin = () => {
useEffect(() => {
if (loading) {
- navigate('/demo');
+ if (location.pathname.startsWith('/local')) {
+ navigate('/local');
+ } else {
+ navigate('/demo');
+ }
setLoading(false);
}
}, []);
@@ -85,15 +90,25 @@ const _useUserAndSpacesForFreeLogin = () => {
email: '',
});
} else {
- setUser({
- photo: '',
- id: 'demo',
- username: 'demo',
- nickname: 'demo',
- email: '',
- });
+ if (location.pathname.startsWith('/local')) {
+ setUser({
+ photo: '',
+ id: 'local',
+ username: 'local',
+ nickname: 'local',
+ email: '',
+ });
+ } else {
+ setUser({
+ photo: '',
+ id: 'demo',
+ username: 'demo',
+ nickname: 'demo',
+ email: '',
+ });
+ }
}
- }, [localTrigger, setLoading, setUser]);
+ }, [localTrigger, location, setLoading, setUser]);
const currentSpaceId: string | undefined = useMemo(() => user?.id, [user]);
diff --git a/libs/utils/src/error-boundary.tsx b/libs/utils/src/ErrorBoundary.tsx
similarity index 100%
rename from libs/utils/src/error-boundary.tsx
rename to libs/utils/src/ErrorBoundary.tsx
diff --git a/libs/utils/src/index.ts b/libs/utils/src/index.ts
index 328458be7d..11decf971a 100644
--- a/libs/utils/src/index.ts
+++ b/libs/utils/src/index.ts
@@ -2,7 +2,7 @@ export * from './types';
export * from './constants';
-export * from './error-boundary';
+export * from './ErrorBoundary';
export * from './date';
diff --git a/package.json b/package.json
index 3c9ce22156..a0e060199e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "toeverything",
- "version": "0.0.0",
+ "version": "0.0.1",
"license": "MIT",
"author": "AFFiNE ",
"scripts": {
@@ -15,6 +15,7 @@
"build:keck": "nx build keck",
"build:venus": "nx build venus",
"build:analytic": "cross-env BUNDLE_ANALYZER=true nx build --skip-nx-cache",
+ "build:check": "pnpm exec nx affected --target=build --parallel=2",
"test": "nx run-many --target test --all",
"check": "nx run-many --target check --all",
"add:components": "nx generate @nrwl/react:library --directory=components --buildable --no-component --no-routing --tags=components",
@@ -26,7 +27,6 @@
"lint:with-cache": "nx run-many --target=lint --all --exclude=components-common,keck,theme",
"format": "nx format",
"format:ci": "nx format:check",
- "type:check": "nx build ligo-virgo",
"prepare": "husky install"
},
"private": true,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 43a0b9910e..802d964374 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -184,7 +184,7 @@ importers:
yjs: ^13.5.41
dependencies:
authing-js-sdk: 4.23.35
- firebase-admin: 11.0.1
+ firebase-admin: 11.0.1_@firebase+app-types@0.7.0
lib0: 0.2.52
lru-cache: 7.13.2
nanoid: 4.0.0
@@ -220,17 +220,21 @@ importers:
'@emotion/react': ^11.10.0
'@emotion/styled': ^11.10.0
'@mui/joy': ^5.0.0-alpha.39
+ i18next: ^21.9.1
image-minimizer-webpack-plugin: ^3.2.3
imagemin: ^8.0.1
imagemin-optipng: ^8.0.0
lozad: ^1.16.0
mini-css-extract-plugin: ^2.6.1
+ react-i18next: ^11.18.4
webpack: ^5.74.0
dependencies:
'@emotion/react': 11.10.0
'@emotion/styled': 11.10.0_@emotion+react@11.10.0
'@mui/joy': 5.0.0-alpha.39_72v32ofbtgpmxm7mhvtx474vfu
+ i18next: 21.9.1
lozad: 1.16.0
+ react-i18next: 11.18.4_i18next@21.9.1
devDependencies:
image-minimizer-webpack-plugin: 3.2.3_5emixpjl54fjyhdvj76qjbw4py
imagemin: 8.0.1
@@ -562,9 +566,6 @@ importers:
dependencies:
ffc-js-client-side-sdk: 1.1.5
- libs/datasource/jwst/pkg:
- specifiers: {}
-
libs/datasource/jwt:
specifiers:
'@types/debug': ^4.1.7
@@ -3179,15 +3180,6 @@ packages:
- utf-8-validate
dev: true
- /@firebase/auth-interop-types/0.1.6_@firebase+util@1.6.3:
- resolution: {integrity: sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==}
- peerDependencies:
- '@firebase/app-types': 0.x
- '@firebase/util': 1.x
- dependencies:
- '@firebase/util': 1.6.3
- dev: false
-
/@firebase/auth-interop-types/0.1.6_pbfwexsq7uf6mrzcwnikj3g37m:
resolution: {integrity: sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==}
peerDependencies:
@@ -3196,7 +3188,6 @@ packages:
dependencies:
'@firebase/app-types': 0.7.0
'@firebase/util': 1.6.3
- dev: true
/@firebase/auth-types/0.11.0_pbfwexsq7uf6mrzcwnikj3g37m:
resolution: {integrity: sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw==}
@@ -3232,19 +3223,6 @@ packages:
'@firebase/util': 1.6.3
tslib: 2.4.0
- /@firebase/database-compat/0.2.4:
- resolution: {integrity: sha512-VtsGixO5mTjNMJn6PwxAJEAR70fj+3blCXIdQKel3q+eYGZAfdqxox1+tzZDnf9NWBJpaOgAHPk3JVDxEo9NFQ==}
- dependencies:
- '@firebase/component': 0.5.17
- '@firebase/database': 0.13.4
- '@firebase/database-types': 0.9.12
- '@firebase/logger': 0.3.3
- '@firebase/util': 1.6.3
- tslib: 2.4.0
- transitivePeerDependencies:
- - '@firebase/app-types'
- dev: false
-
/@firebase/database-compat/0.2.4_@firebase+app-types@0.7.0:
resolution: {integrity: sha512-VtsGixO5mTjNMJn6PwxAJEAR70fj+3blCXIdQKel3q+eYGZAfdqxox1+tzZDnf9NWBJpaOgAHPk3JVDxEo9NFQ==}
dependencies:
@@ -3256,7 +3234,6 @@ packages:
tslib: 2.4.0
transitivePeerDependencies:
- '@firebase/app-types'
- dev: true
/@firebase/database-types/0.9.10:
resolution: {integrity: sha512-2ji6nXRRsY+7hgU6zRhUtK0RmSjVWM71taI7Flgaw+BnopCo/lDF5HSwxp8z7LtiHlvQqeRA3Ozqx5VhlAbiKg==}
@@ -3271,19 +3248,6 @@ packages:
'@firebase/app-types': 0.7.0
'@firebase/util': 1.6.3
- /@firebase/database/0.13.4:
- resolution: {integrity: sha512-NW7bOoiaC4sJCj6DY/m9xHoFNa0CK32YPMCh6FiMweLCDQbOZM8Ql/Kn6yyuxCb7K7ypz9eSbRlCWQJsJRQjhg==}
- dependencies:
- '@firebase/auth-interop-types': 0.1.6_@firebase+util@1.6.3
- '@firebase/component': 0.5.17
- '@firebase/logger': 0.3.3
- '@firebase/util': 1.6.3
- faye-websocket: 0.11.4
- tslib: 2.4.0
- transitivePeerDependencies:
- - '@firebase/app-types'
- dev: false
-
/@firebase/database/0.13.4_@firebase+app-types@0.7.0:
resolution: {integrity: sha512-NW7bOoiaC4sJCj6DY/m9xHoFNa0CK32YPMCh6FiMweLCDQbOZM8Ql/Kn6yyuxCb7K7ypz9eSbRlCWQJsJRQjhg==}
dependencies:
@@ -3295,7 +3259,6 @@ packages:
tslib: 2.4.0
transitivePeerDependencies:
- '@firebase/app-types'
- dev: true
/@firebase/firestore-compat/0.1.23_53yvy43rwpg2c45kgeszsxtrca:
resolution: {integrity: sha512-QfcuyMAavp//fQnjSfCEpnbWi7spIdKaXys1kOLu7395fLr+U6ykmto1HUMCSz8Yus9cEr/03Ujdi2SUl2GUAA==}
@@ -9626,20 +9589,30 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
+ '@babel/runtime': 7.18.6
'@typescript-eslint/parser': 5.30.5_4x5o4skxv6sl53vpwefgt23khm
+ aria-query: 4.2.2
array-includes: 3.1.5
array.prototype.flat: 1.3.0
+ ast-types-flow: 0.0.7
+ axe-core: 4.4.2
+ axobject-query: 2.2.0
+ damerau-levenshtein: 1.0.8
debug: 2.6.9
doctrine: 2.1.0
+ emoji-regex: 9.2.2
eslint: 8.19.0
eslint-import-resolver-node: 0.3.6
eslint-module-utils: 2.7.3_ea34krk32wbcqzxapvwr7rsjs4
has: 1.0.3
is-core-module: 2.9.0
is-glob: 4.0.3
+ jsx-ast-utils: 3.3.1
+ language-tags: 1.0.5
minimatch: 3.1.2
object.values: 1.1.5
resolve: 1.22.1
+ semver: 6.3.0
tsconfig-paths: 3.14.1
transitivePeerDependencies:
- eslint-import-resolver-typescript
@@ -10359,12 +10332,12 @@ packages:
semver-regex: 2.0.0
dev: true
- /firebase-admin/11.0.1:
+ /firebase-admin/11.0.1_@firebase+app-types@0.7.0:
resolution: {integrity: sha512-rL3wlZbi2Kb/KJgcmj1YHlD4ZhfmhfgRO2YJialxAllm0tj1IQea878hHuBLGmv4DpbW9t9nLvX9kddNR2Y65Q==}
engines: {node: '>=14'}
dependencies:
'@fastify/busboy': 1.1.0
- '@firebase/database-compat': 0.2.4
+ '@firebase/database-compat': 0.2.4_@firebase+app-types@0.7.0
'@firebase/database-types': 0.9.10
'@types/node': 18.0.1
jsonwebtoken: 8.5.1
@@ -11184,6 +11157,12 @@ packages:
terser: 5.14.1
dev: true
+ /html-parse-stringify/3.0.1:
+ resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
+ dependencies:
+ void-elements: 3.1.0
+ dev: false
+
/html-webpack-plugin/5.5.0_webpack@5.74.0:
resolution: {integrity: sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==}
engines: {node: '>=10.13.0'}
@@ -11369,6 +11348,12 @@ packages:
hasBin: true
dev: true
+ /i18next/21.9.1:
+ resolution: {integrity: sha512-ITbDrAjbRR73spZAiu6+ex5WNlHRr1mY+acDi2ioTHuUiviJqSz269Le1xHAf0QaQ6GgIHResUhQNcxGwa/PhA==}
+ dependencies:
+ '@babel/runtime': 7.18.6
+ dev: false
+
/iconv-lite/0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@@ -15424,6 +15409,26 @@ packages:
hotkeys-js: 3.9.3
dev: false
+ /react-i18next/11.18.4_i18next@21.9.1:
+ resolution: {integrity: sha512-gK/AylAQC5DvCD5YLNCHW4PNzpCfrWIyVAXbSMl+/5QXzlDP8VdBoqE2s2niGHB+zIXwBV9hRXbDrVuupbgHcg==}
+ peerDependencies:
+ i18next: '>= 19.0.0'
+ react: '>= 16.8.0'
+ react-dom: '*'
+ react-native: '*'
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.18.6
+ html-parse-stringify: 3.0.1
+ i18next: 21.9.1
+ dev: false
+
/react-is/16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
@@ -17679,6 +17684,11 @@ packages:
extsprintf: 1.3.0
dev: true
+ /void-elements/3.1.0:
+ resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/w3c-hr-time/1.0.2:
resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
dependencies:
diff --git a/tools/executors/svgOptimize/executor.json b/tools/executors/svgOptimize/executor.json
deleted file mode 100644
index 1c19a2f9c5..0000000000
--- a/tools/executors/svgOptimize/executor.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "executors": {
- "svgOptimize": {
- "implementation": "./svgo.js",
- "schema": "./schema.json",
- "description": "Run `svgo` (to optimize svg)."
- }
- }
-}
diff --git a/tools/executors/svgOptimize/package.json b/tools/executors/svgOptimize/package.json
deleted file mode 100644
index 721ff1df5d..0000000000
--- a/tools/executors/svgOptimize/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "executors": "./executor.json"
-}
diff --git a/tools/executors/svgOptimize/schema.json b/tools/executors/svgOptimize/schema.json
deleted file mode 100644
index dc2fdc029b..0000000000
--- a/tools/executors/svgOptimize/schema.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "$schema": "http://json-schema.org/schema",
- "type": "object",
- "cli": "nx",
- "properties": {
- "svgOptimize": {
- "type": "string",
- "description": "optimize svg"
- }
- }
-}
diff --git a/tools/executors/svgOptimize/svgo.js b/tools/executors/svgOptimize/svgo.js
deleted file mode 100644
index a0f6c21539..0000000000
--- a/tools/executors/svgOptimize/svgo.js
+++ /dev/null
@@ -1,133 +0,0 @@
-const path = require('path');
-const svgo = require('svgo');
-const { readdir, readFile, writeFile, exists } = require('fs/promises');
-const { pascalCase, paramCase } = require('change-case');
-const svgr = require('@svgr/core');
-
-async function optimizeSvg(folder) {
- try {
- const icons = await readdir(folder);
- const generateIcons = icons
- .filter(n => n.endsWith('.svg'))
- .map(async icon => {
- let originSvg;
- try {
- originSvg = await readFile(path.resolve(folder, icon));
- } catch (err) {
- console.error(err);
- }
- let optimizedSvg;
- try {
- const data = optimize(originSvg);
- optimizedSvg = data.data;
- } catch (err) {
- console.error(err);
- }
-
- const JSXContent = await getJSXContent(
- pascalCase(icon),
- optimizedSvg
- );
-
- const iconName = path.basename(icon, '.svg');
- await writeFile(
- path.resolve(folder, `${iconName}.tsx`),
- JSXContent,
- { encoding: 'utf8', flag: '' }
- );
-
- console.log('Generated:', iconName);
- });
-
- await Promise.allSettled([
- ...generateIcons,
- generateImportEntry(icons, folder),
- ]);
- } catch (err) {
- console.error(err);
- }
-}
-
-function optimize(input) {
- return svgo.optimize(input, {
- plugins: [
- 'preset-default',
- 'prefixIds',
- {
- name: 'sortAttrs',
- params: {
- xmlnsOrder: 'alphabetical',
- },
- },
- ],
- });
-}
-
-/**
- * get icon component template
- *
- * @param {string} name
- */
-async function getJSXContent(name, svgCode) {
- let svgrContent = '';
- try {
- svgrContent = await svgr.transform(
- svgCode,
- {
- icon: true,
- typescript: true,
- },
- { componentName: `${name}Icon1` }
- );
- } catch (err) {
- console.error(err);
- }
- let matcher = svgrContent.match(/]+)>([\s\S]*?)<\/svg>/);
- return `
-import { SvgIcon, SvgIconProps } from '@mui/material';
-export const ${name}Icon = (props: SvgIconProps) => (
-
- ${matcher[2]}
-
-);
-`;
-}
-
-async function generateImportEntry(iconNodes, folder) {
- const fileWithImportsPath = path.resolve(folder, 'index.ts');
-
- const importsContent = iconNodes
- .map(iconNode => {
- const iconName = paramCase(iconNode.name);
- if (!iconName) {
- return `// Error: ${iconNode.name}`;
- }
-
- return `export * from './${iconName}/${iconName}';`;
- })
- .join('\n');
-
- await fs.writeFile(
- fileWithImportsPath,
- `export const timestamp = ${Date.now()};\n${importsContent}`,
- { encoding: 'utf8' }
- );
-}
-
-/**
- * @param {*} options
- * @param {array} options.assets
- * @param {string} options.assets.folder
- * @param {*} context
- * @returns
- */
-exports['default'] = async function svgo(options, context) {
- const libRoot = context.workspace.projects[context.projectName].root;
- await Promise.allSettled(
- (options.assets || []).map(async (asset, index) => {
- await optimizeSvg(path.resolve(libRoot, asset.folder));
- })
- );
-
- return { success: true };
-};