Commit Graph

63 Commits

Author SHA1 Message Date
zzj3720
5a5779c05a feat(editor): simple table block (#9740)
close: BS-2122, BS-2125, BS-2124, BS-2420, PD-2073, BS-2126, BS-2469, BS-2470, BS-2478, BS-2471
2025-01-24 10:07:57 +00:00
doodlewind
872a578bf7 refactor(editor): move zod schema with model for non surface blocks (#9876) 2025-01-23 10:57:49 +00:00
donteatfriedrice
bf797c7a0c feat(editor): support footnote adapter (#9844)
[BS-2373](https://linear.app/affine-design/issue/BS-2373/适配-footnote-adapter)
2025-01-22 06:42:35 +00:00
doouding
1560880abd fix: drag embed block preview (#9791)
Fixes [BS-1518](https://linear.app/affine-design/issue/BS-1518/拖拽一个-embed-view-的-linked-doc,其-indicator-是错误的)
2025-01-20 09:25:05 +00:00
donteatfriedrice
4bd43a698c refactor(editor): refactor linkPreviewer as an extension and remove bookmark service (#9754)
[BS-2427](https://linear.app/affine-design/issue/BS-2427/移除-bookmark-block-service) [BS-2418](https://linear.app/affine-design/issue/BS-2418/linkpreviewer-重构成插件)
2025-01-20 04:18:00 +00:00
L-Sun
6ba802fb17 feat(editor): append note to page button (#9762)
Close [BS-2310](https://linear.app/affine-design/issue/BS-2310/note-display-in-page-%E7%9A%84%E8%A1%8C%E4%B8%BA), [BS-2312](https://linear.app/affine-design/issue/BS-2312/edgeless-note-%E7%9A%84-element-toolbar-%E6%B7%BB%E5%8A%A0display-in-page%E6%8C%89%E9%92%AE) and [BS-2313](https://linear.app/affine-design/issue/BS-2313/添加display-in-page的toast提示,以及打开toc的按钮)
2025-01-19 08:35:02 +00:00
L-Sun
ad814a0f4f feat(editor): add sidebar service (#9761) 2025-01-17 23:42:50 +08:00
donteatfriedrice
df910d7013 feat(editor): add affine inline footnote (#9745)
[BS-2369](https://linear.app/affine-design/issue/BS-2369/新增-affinetextattribute-footnote)  [BS-2370](https://linear.app/affine-design/issue/BS-2370/支持-footnote-自定义渲染行内内容) [BS-2372](https://linear.app/affine-design/issue/BS-2372/提供-footnoteconfigextension) [BS-2375](https://linear.app/affine-design/issue/BS-2375/footnote-自定义渲染-popup)

### Add new AffineTextAttribute: footnote

```
/**
 * FootNote is used to reference a doc, attachment or url.
 */
export interface AffineTextAttributes {
  ...
  footnote?: {
    label: string; // label of the footnote
    reference: {
      type: 'doc' | 'attachment' | 'url'; // type of reference
      docId?: string; // the id of the reference doc
      url?: string; //  the url of the reference network resource
      blobId?: string; // the id of the reference attachment
      fileName?: string; // the name of the reference attachment
      fileType?: string; // the type of the reference attachment
    }
  } | null
}
```

### FootNoteNodeConfigProvider Extension

#### FootNoteNodeConfig Type Definition

```
type FootNoteNodeRenderer = (
  footnote: FootNote,
  std: BlockStdScope
) => TemplateResult<1>;

type FootNotePopupRenderer = (
  footnote: FootNote,
  std: BlockStdScope,
  abortController: AbortController
) => TemplateResult<1>;

export interface FootNoteNodeConfig {
  customNodeRenderer?: FootNoteNodeRenderer;
  customPopupRenderer?: FootNotePopupRenderer;
  interactive?: boolean;
  hidePopup?: boolean;
}
```

#### FootNoteNodeConfigProvider Class

```
export class FootNoteNodeConfigProvider {
  private _customNodeRenderer?: FootNoteNodeRenderer;
  private _customPopupRenderer?: FootNotePopupRenderer;
  private _hidePopup: boolean;
  private _interactive: boolean;

  get customNodeRenderer() {
    return this._customNodeRenderer;
  }

  get customPopupRenderer() {
    return this._customPopupRenderer;
  }

  get doc() {
    return this.std.store;
  }

  get hidePopup() {
    return this._hidePopup;
  }

  get interactive() {
    return this._interactive;
  }

  constructor(
    config: FootNoteNodeConfig,
    readonly std: BlockStdScope
  ) {
    this._customNodeRenderer = config.customNodeRenderer;
    this._customPopupRenderer = config.customPopupRenderer;
    this._hidePopup = config.hidePopup ?? false;
    this._interactive = config.interactive ?? true;
  }

  setCustomNodeRenderer(renderer: FootNoteNodeRenderer) {
    this._customNodeRenderer = renderer;
  }

  setCustomPopupRenderer(renderer: FootNotePopupRenderer) {
    this._customPopupRenderer = renderer;
  }

  setHidePopup(hidePopup: boolean) {
    this._hidePopup = hidePopup;
  }

  setInteractive(interactive: boolean) {
    this._interactive = interactive;
  }
}
```

#### FootNoteNodeConfigProvider Extension

```
export const FootNoteNodeConfigIdentifier =
  createIdentifier<FootNoteNodeConfigProvider>('AffineFootNoteNodeConfig');

export function FootNoteNodeConfigExtension(
  config: FootNoteNodeConfig
): ExtensionType {
  return {
    setup: di => {
      di.addImpl(
        FootNoteNodeConfigIdentifier,
        provider =>
          new FootNoteNodeConfigProvider(config, provider.get(StdIdentifier))
      );
    },
  };
}
```

The footnote node can be extended by this extension.

### FootnoteInlineSpec

```
export const FootNoteInlineSpecExtension = InlineSpecExtension(
  'footnote',
  provider => {
    const std = provider.get(StdIdentifier);
    const config =
      provider.getOptional(FootNoteNodeConfigIdentifier) ?? undefined;
    return {
      name: 'footnote',
      schema: FootNoteSchema.optional().nullable().catch(undefined),
      match: delta => {
        return !!delta.attributes?.footnote;
      },
      renderer: ({ delta }) => {
        return html`<affine-footnote-node
          .delta=${delta}
          .std=${std}
          .config=${config}
        ></affine-footnote-node>`;
      },
      embed: true,
    };
  }
);
```
2025-01-17 09:38:43 +00:00
doouding
99717196c5 refactor: rewrite blocksuite dnd (#9595)
### Changed

- Refactored BlockSuite drag-and-drop using @atlaskit/pragmatic-drag-and-drop/element/adapter.
- Updated block dragging to use the new drag-and-drop infrastructure.

### BlockSuite DND API

Access the BlockSuite drag-and-drop API via `std.dnd`. This is a lightweight wrapper around pragmatic-drag-and-drop, offering convenient generic types and more intuitive option names.

#### Drag payload structure
There's some constrain about drag payload. The whole drag payload looks like this:

```typescript
type DragPayload = {
  entity: {
    type: string
  },
  from: {
    at: 'blocksuite',
    docId: string
  }
}
```
- The `from` field is auto-generated—no need for manual handling.
- The `entity` field is customizable, but it must include a `type`.

All drag-and-drop methods accept a generic type for entity, ensuring more accurate payloads in event handlers.

```typescript
type BlockEntity = {
  type: 'blocks',
  blockIds: string[]
}

dnd.draggable<BlockEntity>({
  element: someElement,
  setDragData: () => {
    // the return type must satisfy the generic type
    // in this case, it's BlockEntity
    return {
      type: 'blocks',
      blockIds: []
    }
  }
});

dnd.monitor<BlockEntity>({
  // the arguments is same for other event handler
  onDrag({ source }) {
    // the type of this is BlockEntity
    source.data.entity
  }
})
```

#### Drop payload
When hover on droppable target. You can set drop payload as well. All drag-and-drop methods accept a second generic type for drop payload.

The drop payload is customizable. Additionally, the DND system will add an `edge` field to the final payload object, indicating the nearest edge of the drop target relative to the current drag position.

```typescript
type DropPayload = {
  blockId: string;
}

dnd.dropTarget<BlockEntity, DropPayload>({
  getData() {
    // the type should be DropPayload
    return {
      blockId: 'someId'
    }
  }
});

dnd.monitor<BlockEntity, DropPayload>({
  // drag over on drop target
  onDrag({ location }) {
    const target = location.current.dropTargets[0];

    // the type is DropPayload
    target.data;
    // retrieve the nearest edge of the drop target relative to the current drop position.
    target.data.edge;
  }
})
```
2025-01-16 12:36:58 +00:00
L-Sun
94c9717a35 feat(editor): edgeless page block toolbar (#9707)
Close [BS-2315](https://linear.app/affine-design/issue/BS-2315/page-block-header)

### What Changes
- Add header toolbar to page block (the first note in canvas)
- Add e2e tests
- Add some edgeless e2e test utils.  **The package `@blocksuite/affine` was added to `"@affine-test/kit"`**
2025-01-15 12:04:44 +00:00
donteatfriedrice
4f421efb22 fix(editor): init default theme observer value according to data-theme (#9698) 2025-01-15 04:04:06 +00:00
donteatfriedrice
5c4e87ddb5 feat(editor): support text highlight html adapter (#9632)
[BS-2061](https://linear.app/affine-design/issue/BS-2061/html-adapter-支持-text-highlight-样式)
2025-01-13 02:20:58 +00:00
Mirone
446b31b621 refactor(editor): rename job to transformer (#9639) 2025-01-11 12:04:07 +08:00
fundon
0b3dba614d perf(editor): optimize the search for the closest element (#9587)
Closes: [BS-2275](https://linear.app/affine-design/issue/BS-2275/拖拽-indicator-查找优化)
2025-01-10 08:21:10 +00:00
Saul-Mirone
126ab18967 feat(editor): selection as store extension (#9605) 2025-01-09 11:49:23 +00:00
pengx17
f78857bb11 feat(editor): add more open doc options to editor toolbar (#9588)
fix AF-2036, AF-2092
2025-01-09 08:04:21 +00:00
Saul-Mirone
d21ef47ae8 chore(editor): rename std.doc to std.store (#9596) 2025-01-09 04:16:28 +00:00
Saul-Mirone
3683297ccf feat(editor): add feature flag service (#9592) 2025-01-08 15:46:31 +00:00
Saul-Mirone
5842d45ab1 feat(editor): merge store and blocks (#9591) 2025-01-08 13:01:19 +00:00
L-Sun
440239809c refactor(editor): refactor page note empty checker (#9570)
Close [BS-2320](https://linear.app/affine-design/issue/BS-2320/内容为空的状态判断)
2025-01-07 11:24:40 +00:00
donteatfriedrice
52f2e8d5d5 refactor(editor): surface markdown adapter extensionalize (#9560)
[BS-2212](https://linear.app/affine-design/issue/BS-2212/adapter-extension化修复)
2025-01-07 03:14:08 +00:00
donteatfriedrice
69e9aa087e refactor(editor): extract mix-text adapter to shared (#9559) 2025-01-07 03:14:07 +00:00
fundon
69e73af2a8 refactor(editor): add native clipboard extension (#9502)
Closes: [BS-2239](https://linear.app/affine-design/issue/BS-2239/不应该通过window注入affine的api)
2025-01-06 15:36:43 +00:00
Saul-Mirone
f778d1a28a refactor(editor): move extension to store (#9552) 2025-01-06 15:15:14 +00:00
Saul-Mirone
fc863e484c refactor(editor): remove selection global types (#9532)
Closes: [BS-2217](https://linear.app/affine-design/issue/BS-2217/remove-global-types-in-selection)
2025-01-06 03:45:11 +00:00
Saul-Mirone
c773982ced refactor(editor): rename store api (#9518) 2025-01-04 12:51:56 +00:00
Saul-Mirone
dcf4993265 refactor(core): move block collection to affine and implement as doc (#9514) 2025-01-04 06:28:55 +00:00
Saul-Mirone
4457cb7266 refactor(editor): rename doc to blocks (#9510) 2025-01-03 12:49:33 +00:00
Flrande
2074bda8ff fix(editor): at menu position in split view (#9500) 2025-01-03 12:20:31 +00:00
Saul-Mirone
897c7d4284 refactor(editor): should not rely on doc collection type (#9501) 2025-01-03 06:30:27 +00:00
doouding
cb5d7eaabc feat: add scroll wheel zoom setting (#9476)
### Changed
Add `scroll wheel to zoom` setting option, when the option enables, user can zoom in and out with scroll wheel without pressing the cmd/ctrl key.
2025-01-03 06:09:10 +00:00
Saul-Mirone
8b6c81f76d refactor(editor): reduce dependency to doc collection (#9492) 2025-01-03 01:59:25 +00:00
Saul-Mirone
edb5e1d87a refactor(editor): job should not rely on doc collection directly (#9488) 2025-01-02 10:50:15 +00:00
Flrande
72e343c379 fix(editor): replace checkVisibility (#9481) 2025-01-02 08:25:48 +00:00
Saul-Mirone
ad422d2f05 refactor(editor): move crud to doc (#9479) 2025-01-02 07:27:08 +00:00
Saul-Mirone
597b631918 refactor(editor): extract color picker component (#9456) 2024-12-31 07:23:37 +00:00
Saul-Mirone
09427e846e refactor(editor): extract markdown adapter (#9443) 2024-12-31 04:13:02 +00:00
Saul-Mirone
ade317d26b fix(editor): caret can be null in firefox (#9438)
Fix: https://toeverything.sentry.io/issues/6185588184/events/b205b6caf0224b51882c1d10bb3dd9bc/
2024-12-30 14:44:11 +00:00
Saul-Mirone
a9f890017e fix(editor): missing dependencies (#9436) 2024-12-30 14:10:37 +00:00
Saul-Mirone
b66a64bc9a refactor(editor): use spec builder (#9424) 2024-12-30 08:42:58 +00:00
Saul-Mirone
e3b6841944 refactor(editor): reorg block specs (#9421) 2024-12-30 05:59:25 +00:00
fundon
b9f2650369 feat(editor): store real color values in edgeless (#9254)
### What's Changed!

* adds theme type: `ThemeSchema`
* adds default theme: `DefaultTheme`
* stores real color values
2024-12-30 03:36:35 +00:00
fundon
a5641ae608 feat(editor): update edgeless color palette (#9243)
Closes: [BS-1475](https://linear.app/affine-design/issue/BS-1475/颜色主题更新) [BS-1803](https://linear.app/affine-design/issue/BS-1803/fill-color色板影响的yuan素) [BS-1804](https://linear.app/affine-design/issue/BS-1804/border-color色板影响的yuan素) [BS-1815](https://linear.app/affine-design/issue/BS-1815/连线文字配色略瞎)

### What's Changed

* refactor `EdgelessLineWidthPanel` component, the previous width is fixed and cannot be used in the new design
* refactor `EdgelessColorPanel` and `EdgelessColorButton` components, make them simple and reusable
* delete redundant `EdgelessOneRowColorPanel` component
* unity and update color palette, if the previously set color is not in the latest color palette, the custom color button will be selected
2024-12-30 03:36:34 +00:00
Saul-Mirone
6b1865ff92 fix(editor): prevent errors from isStrictUrl (#9419)
Closes: [BS-2277](https://linear.app/affine-design/issue/BS-2277/typeerror-failed-to-construct-url-invalid-url)
2024-12-30 02:45:59 +00:00
Saul-Mirone
cec4a4b2c0 refactor(editor): extract drag handle widget (#9415) 2024-12-29 06:51:48 +00:00
Saul-Mirone
1e4b1807be refactor(editor): query methods in edgeless api (#9407) 2024-12-28 07:48:41 +00:00
Saul-Mirone
901965b61e refactor(editor): remove components in blocks/_common (#9401) 2024-12-28 01:10:23 +00:00
doodlewind
5e1d936c2e fix(editor): sentry-b0cfc9953ff64c53b9994697171bb91a (#9396) 2024-12-27 14:02:00 +00:00
Saul-Mirone
cbfe38b189 refactor(editor): add middlewares in shared adapter (#9395) 2024-12-27 12:32:44 +00:00
donteatfriedrice
fee86304ae refactor(editor): extract adapters to shared (#9344)
Extract AttachmentAdapter, ImageAdapter, NotionTextAdapter to shared.
2024-12-27 08:52:03 +00:00