Skip to content

Commit

Permalink
docs: reorg guide and reference sidebar (#6115)
Browse files Browse the repository at this point in the history
  • Loading branch information
doodlewind authored Jan 25, 2024
1 parent 0eb046d commit 3a6ab05
Show file tree
Hide file tree
Showing 62 changed files with 260 additions and 250 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ BlockSuite is a toolkit for building collaborative editors and applications. It
- [**`DocEditor`**](https://blocksuite.io/presets/doc-editor.html): **Built entirely from scratch**, `DocEditor` is a comprehensive block-based document editor, offering extensive customization and flexibility.
- [**`EdgelessEditor`**](https://blocksuite.io/presets/edgeless-editor.html): **Featuring canvas-based graphics rendering** at its core with sophisticated rich-text features, `EdgelessEditor` offers unique functionalities and decent performance in whiteboard editing.

![showcase-doc-edgeless-editors](./packages/docs/main/images/showcase-doc-edgeless-editors.jpg)
![showcase-doc-edgeless-editors](./packages/docs/images/showcase-doc-edgeless-editors.jpg)

The BlockSuite project is structured around key packages that are categorized into two groups: a headless framework and prebuilt editing components.

Expand Down Expand Up @@ -72,7 +72,7 @@ The BlockSuite project is structured around key packages that are categorized in

This can be illustrated as the diagram below:

![package-overview.png](./packages/docs/main/images/package-overview.png)
![package-overview.png](./packages/docs/images/package-overview.png)

In addition to extending custom blocks, here are what you can also conveniently achieve with BlockSuite:

Expand Down
File renamed without changes.
210 changes: 210 additions & 0 deletions packages/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import { DefaultTheme, defineConfig } from 'vitepress';
import wasm from 'vite-plugin-wasm';
import container from 'markdown-it-container';
import { renderSandbox } from 'vitepress-plugin-sandpack';

const guide: DefaultTheme.NavItem[] = [
{
text: 'Getting Started',
items: [
{ text: 'Overview', link: 'guide/overview' },
{ text: 'Quick Start', link: 'guide/quick-start' },
],
},
{
text: 'Framework Tutorial',
items: [
{ text: 'Component Types', link: 'guide/component-types' },
{
text: 'Working with Block Tree',
// @ts-ignore
link: 'guide/working-with-block-tree',
items: [
{
text: 'Block Tree Basics',
link: 'guide/working-with-block-tree#block-tree-basics',
},
{
text: 'Block Tree in Editor',
link: 'guide/working-with-block-tree#block-tree-in-editor',
},
{
text: 'Selecting Blocks',
link: 'guide/working-with-block-tree#selecting-blocks',
},
{
text: 'Service and Commands',
link: 'guide/working-with-block-tree#service-and-commands',
},
{
text: 'Defining New Blocks',
link: 'guide/working-with-block-tree#defining-new-blocks',
},
],
},
{ text: 'Data Synchronization', link: 'guide/data-synchronization' },
],
},
{
text: 'Editor In-Depth',
items: [
// { text: 'Design Philosophy', link: 'guide/design-philosophy' },
{
text: 'CRDT-Native Data Flow',
link: 'guide/crdt-native-data-flow',
},
],
},
{
text: 'API Walkthrough',
items: [
{
text: '<code>block-std</code>',
items: [
{
text: 'Block Spec',
link: 'guide/block-spec',
// @ts-ignore
items: [
{ text: 'Block Schema', link: 'guide/block-schema' },
{ text: 'Block Service', link: 'guide/block-service' },
{ text: 'Block View', link: 'guide/block-view' },
{ text: 'Block Widgets', link: 'guide/block-widgets' },
],
},
{
text: 'Selection',
link: 'guide/selection',
},
{ text: 'Event', link: 'guide/event' },
{ text: 'Command', link: 'guide/command' },
],
},
{
text: '<code>store</code>',
items: [
{ text: 'Page', link: 'guide/store#page' },
{ text: 'Workspace', link: 'guide/store#workspace' },
{ text: 'Slot', link: 'guide/slot' },
{ text: 'Adapter', link: 'guide/adapter' },
],
},
{
text: '<code>inline</code>',
link: 'guide/inline',
},
{
text: '<code>lit</code>',
link: 'guide/lit',
},
],
},
{
text: 'Developing BlockSuite',
items: [
{
text: 'Building Packages',
link: '//github.com/toeverything/blocksuite/blob/master/BUILDING.md',
},
{
text: 'Running Tests',
link: '//github.com/toeverything/blocksuite/blob/master/BUILDING.md#testing',
},
],
},
];

const reference: DefaultTheme.NavItem[] = [
{
text: 'API Reference',
items: [
{ text: '@blocksuite/store', link: 'api/@blocksuite/store/index' },
{
text: '@blocksuite/block-std',
link: 'api/@blocksuite/block-std/index',
},
{ text: '@blocksuite/lit', link: 'api/@blocksuite/lit/index' },
{ text: '@blocksuite/inline', link: 'api/@blocksuite/inline/index' },
{
text: '@blocksuite/presets',
link: 'api/@blocksuite/presets/index',
},
{ text: '@blocksuite/blocks', link: 'api/@blocksuite/blocks/index' },
],
},
];

// https://vitepress.dev/reference/site-config
export default defineConfig({
vite: {
build: {
target: 'ES2022',
},
plugins: [wasm()],
},
lang: 'en-US',
title: 'BlockSuite',
description: 'The Editor Framework',
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
nav: [
{
text: 'Presets',
items: [
{ text: '📝 DocEditor', link: '/presets/doc-editor' },
{ text: '🎨 EdgelessEditor', link: '/presets/edgeless-editor' },
],
},
{ text: 'Guide', link: '/guide/overview' },
{ text: 'API', link: '/api/' },
// { text: 'Blog', link: '#' },
{
text: 'Releases',
link: 'https://github.com/toeverything/blocksuite/releases',
},
],

sidebar: {
'/guide/': { base: '/', items: guide },
'/api/': { base: '/', items: reference },
},

socialLinks: [
{ icon: 'github', link: 'https://github.com/toeverything/blocksuite' },
{
icon: {
svg: '<svg role="img" xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path fill="#777777" d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"/></svg>',
},
link: 'https://twitter.com/AffineDev',
},
],

footer: {
copyright: 'Copyright © 2022-present Toeverything',
},

search: {
provider: 'local',
},
},
head: [
[
'link',
{
rel: 'icon',
type: 'image/png',
sizes: '32x32',
href: 'https://raw.githubusercontent.com/toeverything/blocksuite/master/assets/logo.svg',
},
],
],
markdown: {
config(md) {
md.use(container, 'code-sandbox', {
render(tokens, idx) {
return renderSandbox(tokens, idx, 'code-sandbox');
},
});
},
},
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A block spec contains the following properties:
- `component`: The primary user interface element of the block.
- `widgets`: Additional interactive elements enhancing the block's functionality.

![block-spec](./images/block-spec.png)
![block-spec](../images/block-spec.png)

## Lit-Based Example

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ The `@blocksuite/presets` package includes reusable editors like `DocEditor` and

The distinction between editors and fragments lies in their complexity and functionality. **Fragments typically offer more simplified capabilities, serving specific UI purposes, whereas editors provide comprehensive editing capabilities over the block tree**. Nevertheless, both editors and fragments shares similar tech stacks and [data flows](./crdt-native-data-flow).

![showcase-fragments-2](./images/showcase-fragments-2.jpg)
![showcase-fragments-2](../images/showcase-fragments-2.jpg)

## Blocks and Widgets

To address the complexity and diversity of editing needs, BlockSuite architects its editors as assemblies of multiple editable blocks, termed [`BlockSpec`](./block-spec)s. Each block spec encapsulates the data schema, view, service, and logic required to compose the editor. These block specs collectively define the editable components within the editor's environment.

Within each block spec, there can be [`Widget`](./block-widgets)s specific to that block's implementation, enhancing interactivity within the editor. BlockSuite leverages this widget mechanism to register dynamic UI components such as drag handles and slash menus within the doc editor.

![component-types](./images/component-types.png)
![component-types](../images/component-types.png)

## Composing Editors by Blocks

Expand Down Expand Up @@ -66,15 +66,15 @@ With very little overhead.

So, as long as there is a corresponding `host` implementation, you can use the component model of frameworks like react or vue to implement your BlockSuite editors:

![framework-agnostic](./images/framework-agnostic.png)
![framework-agnostic](../images/framework-agnostic.png)

Explore the [`DocEditor` source code](https://github.com/toeverything/blocksuite/blob/master/packages/presets/src/editors/doc-editor.ts) to see how this pattern allows composing minimal real-world editors.

## One Block, Multiple Specs

BlockSuite encourages the derivation of various block spec implementations from a single block model to enrich the editing experience. For instance, the root node of the block tree, the _page block_, is implemented differently for `DocEditor` and `EdgelessEditor` through two different specs **but with the same shared `PageBlockModel`**. The two block specs serve as the top-level UI components for their respective editors:

![showcase-doc-edgeless-editors](./images/showcase-doc-edgeless-editors.jpg)
![showcase-doc-edgeless-editors](../images/showcase-doc-edgeless-editors.jpg)

This allows you to **implement various editors easily on top of the same document**, providing diverse editing experiences and great potentials in customizability.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Traditionally, CRDTs have often been seen as a technology specialized in conflic
- When the local model is updated, the state of the native model is synchronized to the CRDT model.
- When a remote peer is updated, the data resolved from the CRDT model is synchronized back to the native model.

![bidirectional-data-flow](./images/bidirectional-data-flow.png)
![bidirectional-data-flow](../images/bidirectional-data-flow.png)

Although this is an intuitive and common practice, it requires synchronization between two heterogeneous models, resulting in a bidirectional data flow. The main issues here are:

Expand All @@ -30,7 +30,7 @@ As an alternative, BlockSuite chooses to directly use the CRDT model as the sing

This design can be represented by the following diagram:

![crdt-native-data-flow](./images/crdt-native-data-flow.png)
![crdt-native-data-flow](../images/crdt-native-data-flow.png)

The advantage of this approach is that the application-layer code can **completely ignore whether updates to the block model come from local editing, history stack, or collaboration with other users**. Just subscribing to model update events is adequate.

Expand All @@ -46,7 +46,7 @@ The complete state update process in BlockSuite involves several distinct steps,
2. **State Manipulation via Commands**: Commands can manipulate the editor state to accomplish UI updates.
3. **State-Driven View Updates**: Upon state changes, slot events are used to notify and update view components accordingly.

![block-std-data-flow](./images/block-std-data-flow.png)
![block-std-data-flow](../images/block-std-data-flow.png)

This update mechanism is depicted in the diagram above. Concepts such as [command](./command), [view](./block-view) and [event](./event) are further elaborated in other documentation sections for detailed understanding.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ In both cases, whether the document is **loaded** or **created**, the [`page.slo

Furthermore, by connecting multiple providers, documents can automatically be synchronized to a variety of different backends:

![pluggable-providers](./images/pluggable-providers.png)
![pluggable-providers](../images/pluggable-providers.png)

This brings great flexibility and is the pattern currently being used in [AFFiNE](https://github.com/toeverything/AFFiNE).
Loading

2 comments on commit 3a6ab05

@vercel
Copy link

@vercel vercel bot commented on 3a6ab05 Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

blocksuite – ./packages/playground

try-blocksuite.vercel.app
blocksuite-toeverything.vercel.app
blocksuite-git-master-toeverything.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 3a6ab05 Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.