Skip to content

feat: multi UI libs (shadcn + ariakit) + i18n #652

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6406daf
wip
matthewlipski Mar 6, 2024
184d36c
Refactored image toolbar
matthewlipski Mar 6, 2024
861c2b2
Refactored image toolbar, hyperlink toolbar, and table handles
matthewlipski Mar 7, 2024
68d7df5
Implemented PR feedback
matthewlipski Mar 8, 2024
c29b63f
Implemented PR feedback
matthewlipski Mar 11, 2024
89fb722
Cleaned up component code
matthewlipski Mar 12, 2024
7318c51
wip: ariakit
YousefED Mar 14, 2024
a7f908f
wip
YousefED Mar 18, 2024
dca9fe7
Merge remote-tracking branch 'TypeCellOS/main' into refactor/multi-ui…
YousefED Mar 18, 2024
f0b20bd
fix
YousefED Mar 18, 2024
9ef1634
fix merge
YousefED Mar 18, 2024
11a7247
wip
YousefED Mar 18, 2024
af65c67
wip
YousefED Mar 19, 2024
00c296c
fix
YousefED Mar 19, 2024
c268f7c
wip
YousefED Mar 19, 2024
9167f18
wip
YousefED Mar 20, 2024
25237b4
wip: suggestionmenu
YousefED Mar 22, 2024
9f877c1
extract suggestion menu
YousefED Mar 22, 2024
567df48
wip
YousefED Mar 22, 2024
234612c
side menu button
YousefED Mar 22, 2024
5316b69
move mantine elements to mantine dir
YousefED Mar 22, 2024
8a0f526
shadcn wip
YousefED Mar 22, 2024
2ae2e91
wip
YousefED Mar 26, 2024
d20269b
fix
YousefED Mar 26, 2024
a5cf36a
shadcn fixes
YousefED Mar 26, 2024
c2fb7f3
Merge remote-tracking branch 'origin/main' into refactor/multi-ui-libs
YousefED Apr 5, 2024
600f0c5
refactor: Extract image panel components (#684)
matthewlipski Apr 30, 2024
8284895
Revert "refactor: Extract image panel components (#684)" (#716)
matthewlipski Apr 30, 2024
64c12ac
refactor: Extract image panel components (#717)
matthewlipski Apr 30, 2024
5413b34
Updated package versions
matthewlipski Apr 30, 2024
6e5f1d3
Updated screenshots
matthewlipski Apr 30, 2024
ac99d31
Updated screenshots
matthewlipski Apr 30, 2024
7293f64
Updated screenshots
matthewlipski Apr 30, 2024
dfb9436
Updated screenshots
matthewlipski Apr 30, 2024
684a592
Updated docs
matthewlipski Apr 30, 2024
518ee8e
Addressed most TODOs and small fixes
matthewlipski Apr 30, 2024
39d84a0
Added ShadCN form
matthewlipski Apr 30, 2024
06ddfc0
update docs
YousefED May 1, 2024
85f597d
i18n + docs
YousefED May 1, 2024
2c025f8
Updated theming code
matthewlipski May 2, 2024
3987ceb
Merge remote-tracking branch 'origin/refactor/multi-ui-libs' into ref…
matthewlipski May 2, 2024
24e9e59
fix build and lint
YousefED May 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module.exports = {
},
},
},
ignorePatterns: ["**/ui/*"],
rules: {
curly: 1,
"import/no-extraneous-dependencies": [
Expand Down
5 changes: 3 additions & 2 deletions docs/components/pages/landing/hero/DemoEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { uploadToTmpFilesDotOrg_DEV_ONLY } from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView, useCreateBlockNote } from "@blocknote/react";
import "@blocknote/react/style.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { useCallback, useMemo, useState } from "react";
import YPartyKitProvider from "y-partykit/provider";
import * as Y from "yjs";
Expand Down
3 changes: 3 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"dependencies": {
"@blocknote/core": "^0.12.4",
"@blocknote/react": "^0.12.4",
"@blocknote/ariakit": "^0.12.4",
"@blocknote/mantine": "^0.12.4",
"@blocknote/shadcn": "^0.12.4",
"@headlessui/react": "^1.7.18",
"@mantine/core": "^7.7.1",
"@next/bundle-analyzer": "^14.1.0",
Expand Down
16 changes: 16 additions & 0 deletions docs/pages/docs/advanced/ariakit.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: BlockNote with Ariakit
description: Ariakit rich text editor with BlockNote
imageTitle: BlockNote with Ariakit
---

import { Example } from "@/components/example";
import { Callout } from "nextra/components";

## Using Ariakit with BlockNote

[Ariakit](https://ariakit.org/) is an open-source library of unstyled (headless), primitive components with a focus on Accessibility. To use BlockNote with Ariakit, you can import `BlockNoteView` from `@blocknote/ariakit` (instead of from `@blocknote/mantine`).

You can fully style the components with your own CSS, or import the provided default styles using the CSS file from `@blocknote/ariakit/style.css`.

<Example name="basic/ariakit" />
95 changes: 95 additions & 0 deletions docs/pages/docs/advanced/component-libraries.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: Using Other Component Libraries
description: While BlockNote's default UI uses the Mantine component library, you can configure it to use other libraries instead.
imageTitle: Use with Other Component Libraries
path: /docs/component-libraries
---

import { Callout } from "nextra/components";
import { Example } from "@/components/example";

# Using Other Component Libraries

While BlockNote's default UI uses the [Mantine](https://mantine.dev/) component library, you can configure it to use other libraries instead.

## Using Ariakit/ShadCN

BlockNote has plug & play support for [Ariakit](https://ariakit.org/) and [ShadCN](https://ui.shadcn.com/). You can switch to them just by importing `BlockNoteView` from either `@blocknote/ariakit` or `@blocknote/shadcn` instead of `@blocknote/mantine`, as well as the corresponding CSS file.

<Example name="basic/ariakit" />

<Example name="basic/shadcn" />

## ShadCN Customization

If you want BlockNote to use customized ShadCN components instead of the default ones, you can pass them using the `shadCNComponents` prop of `BlockNoteView`:

```tsx
return (
<BlockNoteView editor={editor} shadCNComponents={{
Select: {
SelectTrigger: ...,
SelectContent: ...,
...
},
Button: {
...
},
...
}} />
);
```

You can pass components from the following ShadCN modules:

- Badge
- Button
- Card
- DropdownMenu
- Form
- Input
- Label
- Popover
- Select
- Tabs
- Toggle
- Tooltip

<Callout type="warning" emoji="⚠️">
To ensure compatibility, your ShadCN components should not use Portals, as styling and CSS variables are scoped to only the editor.
</Callout>

## Using Your Own Components

If you want to use a different component library to Mantine/Ariakit/ShadCN, you will have to provide your own `BlockNoteView` implementation using the `BlockNoteViewRaw` component and a `ComponentsContext`:

```tsx
import { BlockSchema, InlineContentSchema, StyleSchema } from "@blocknote/core";
import {
BlockNoteViewRaw,
Components,
ComponentsContext,
} from "@blocknote/react";
import { ComponentProps } from "react";

export const components: Components = {
...
};

export const BlockNoteView = <
BSchema extends BlockSchema,
ISchema extends InlineContentSchema,
SSchema extends StyleSchema
>(
props: ComponentProps<typeof BlockNoteViewRaw<BSchema, ISchema, SSchema>>
) => {
return (
<ComponentsContext.Provider value={components}>
<BlockNoteViewRaw {...props} />
</ComponentsContext.Provider>
);
};
```

The components you want BlockNote to use should be added to `components`. To see exactly how this object is structured, which components you need to provide, and what props each component should take, see [this source file](https://github.com/TypeCellOS/BlockNote/tree/main/packages/react/src/editor/ComponentsContext.tsx).

1 change: 0 additions & 1 deletion docs/pages/docs/advanced/nextjs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
title: Next.js and BlockNote
description: Details on integrating BlockNote with Next.js
imageTitle: Next.js and BlockNote
path: /docs/nextjs
---

# Next.js and BlockNote
Expand Down
1 change: 0 additions & 1 deletion docs/pages/docs/advanced/real-time-collaboration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
title: Real-time Collaborative rich text editor
description: Let's see how you can add Multiplayer capabilities to your BlockNote setup, and allow real-time collaboration between users (similar to Google Docs)
imageTitle: Real-time Collaboration
path: /docs/real-time-collaboration
---

# Real-time Collaboration (multiplayer text editor)
Expand Down
52 changes: 52 additions & 0 deletions docs/pages/docs/advanced/shadcn.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: BlockNote with ShadCN and Tailwind
description: ShadCN + Tailwind rich text editor using BlockNote
imageTitle: BlockNote with ShadCN and Tailwind
---

import { Example } from "@/components/example";
import { Callout } from "nextra/components";

## Using ShadCN, Radix and Tailwind with BlockNote

[shadcn/ui](https://ui.shadcn.com/) is an open-source collection of React components based on [Radix](https://radix-ui.com/) and Tailwind. To use BlockNote with shadcn, you can import `BlockNoteView` from `@blocknote/shadcn` (instead of from `@blocknote/mantine`) and the stylesheet from `@blocknote/shadcn/style.css`.

<Example name="basic/shadcn" />

## ShadCN Customization

BlockNote comes with default shadcn components. However, it's likely that you have copied and possibly customized your own shadcn components in your project.
To make BlockNote use the ShadCN components from your project instead of the default ones, you can pass them using the `shadCNComponents` prop of `BlockNoteView`:

```tsx
import * as Button from "@/components/ui/button"
import * as Select from "@/components/ui/select"

return (
<BlockNoteView editor={editor} shadCNComponents={{
Select,
Button,
...
}} />
);
```

You can pass components from the following ShadCN modules:

- Badge
- Button
- Card
- DropdownMenu
- Form
- Input
- Label
- Popover
- Select
- Tabs
- Toggle
- Tooltip

<Callout type="warning" emoji="⚠️">
To ensure compatibility, your ShadCN components should not use Portals
(comment these out from your DropdownMenu, Popover and Select components).
</Callout>
1 change: 0 additions & 1 deletion docs/pages/docs/advanced/vanilla-js.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
title: Usage Without React (Vanilla JS)
description: BlockNote is mainly designed as a quick and easy drop-in block-based editor for React apps, but can also be used in vanilla JavaScript apps.
imageTitle: Usage Without React (Vanilla JS)
path: /docs/vanilla-js
---

import { Callout } from "nextra/components";
Expand Down
3 changes: 3 additions & 0 deletions docs/pages/docs/editor-basics/setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type BlockNoteEditorOptions = {
defaultStyles?: boolean;
uploadFile?: (file: File) => Promise<string>;
collaboration?: CollaborationOptions;
dictionary?: Dictionary;
schema?: BlockNoteSchema;
};
```
Expand All @@ -42,6 +43,8 @@ The hook takes two optional parameters:

`collaboration`: Options for enabling real-time collaboration. See [Real-time Collaboration](/docs/advanced/real-time-collaboration) for more info.

`dictionary`: Provide strings for localization. See the [Localization / i18n example](/examples/basic/localization).

`schema` (_advanced_): The editor schema if you want to extend your editor with custom blocks, styles, or inline content [Custom Schemas](/docs/custom-schemas).

**deps:** Dependency array that's internally passed to `useMemo`. A new editor will only be created when this array changes.
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/docs/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Getting started with BlockNote is quick and easy. Install the required packages
To install BlockNote with [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), run:

```console
npm install @blocknote/core @blocknote/react
npm install @blocknote/core @blocknote/react @blocknote/mantine
```

## Creating an Editor
Expand All @@ -26,7 +26,7 @@ With the `useCreateBlockNote` hook, we can create a new editor instance, then us

<Example name="basic/minimal" />

We also import `@blocknote/react/style.css` to add default styling for the editor and the `Inter` font that BlockNote exports (optional).
We also import `@blocknote/mantine/style.css` to add default styling for the editor and the `Inter` font that BlockNote exports (optional).

<Callout type="warning" emoji={""}>
<strong>Next.js usage (or other server-side React frameworks)</strong>
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/docs/styling-theming/themes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { Example } from "@/components/example";

Themes let you quickly change the basic look of the editor UI, including colors, borders, shadows, and font. If you want to set more complex styles on the editor, see [Overriding CSS](/docs/styling-theming/overriding-css).

_Themes are only available when using the default Mantine components. ShadCN / Ariakit components can be styled differently._

## Theme CSS Variables

A theme is made up of a set of CSS variables, which can be overwritten to change the editor theme. BlockNote comes with two default themes, one for light and one for dark mode, which are selected based on system preference.
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/docs/ui-components/_meta.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"side-menu": "Block Side Menu",
"formatting-toolbar": "Formatting Toolbar",
"link-toolbar": {
"hyperlink-toolbar": {
"title": "Link Toolbar",
"display": "hidden"
},
Expand Down
11 changes: 2 additions & 9 deletions docs/pages/docs/ui-components/formatting-toolbar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,14 @@ You can change or replace the Formatting Toolbar with your own React component.

<Example name="ui-components/formatting-toolbar-buttons" />

We first define our custom `BlueButton`. The `useComponentsContext` hook gets all components used internally by BlockNote, so we want to use `Components.FormattingToolbar.Button` for this.

We use the `FormattingToolbar` component to create a custom Formatting Toolbar. By specifying its children, we can replace the default buttons in the toolbar with our own.

This custom Formatting Toolbar is passed to a `FormattingToolbarController`, which controls its position and visibility (above or below the highlighted text).

Setting `formattingToolbar={false}` on `BlockNoteView` tells BlockNote not to show the default Formatting Toolbar.

<div className="nx-mt-6 nx-leading-7 first:nx-mt-0">
<small>
<strong>Tip:</strong> The children you pass to the `FormattingToolbar` component
should be default selects/buttons (e.g. `BlockTypeSelect` & `BasicTextStyleButton`) or custom selects/buttons
(`ToolbarSelect` & `ToolbarButton`). To see all the components you can use, head to the
[Formatting Toolbar's source code](https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/FormattingToolbar/mantine/FormattingToolbar.tsx).
</small>
</div>

## Changing Block Type Select (Dropdown) Items

The first element in the default Formatting Toolbar is the Block Type Select, and you can change the items in it. The demo makes the Block Type Select work for image blocks by adding an item to it.
Expand Down
13 changes: 3 additions & 10 deletions docs/pages/docs/ui-components/hyperlink-toolbar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,12 @@ TODO Image

You can change or replace the Link Toolbar with your own React component. In the demo below, a button is added to the default Link Toolbar, which opens a browser alert.

[//]: # (<Example name="ui-components/link-toolbar-buttons" />)
[//]: # '<Example name="ui-components/link-toolbar-buttons" />'

We first define our custom `AlertButton`. The `useComponentsContext` hook gets all components used internally by BlockNote, so we want to use `Components.LinkToolbar.Button` for this.

We use the `LinkToolbar` component to create a custom Link Toolbar. By specifying its children, we can replace the default buttons in the toolbar with our own.

This custom Link Toolbar is passed to a `LinkToolbarController`, which controls its position and visibility (above or below the hovered link).

Setting `linkToolbar={false}` on `BlockNoteView` tells BlockNote not to show the default Link Toolbar.

<div className="nx-mt-6 nx-leading-7 first:nx-mt-0">
<small>
<strong>Tip:</strong> The children you pass to the `LinkToolbar`
component should be default buttons (e.g. TODO) or custom selects/buttons
(`ToolbarSelect` & `ToolbarButton`). To see all the components you can
use, head to the [Link Toolbar's source code](link).
</small>
</div>
11 changes: 2 additions & 9 deletions docs/pages/docs/ui-components/side-menu.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,14 @@ You can change or replace the Block Side Menu with your own React component. In

<Example name="ui-components/side-menu-buttons" />

We first define our custom `RemoveBlockButton`. The `useComponentsContext` hook gets all components used internally by BlockNote, so we want to use `Components.SideMenu.Button` for this.

We use the `SideMenu` component to create a custom Block Side Menu. By specifying its children, we can replace the default buttons in the menu with our own.

This custom Side Menu is passed to a `SideMenuController`, which controls its position and visibility (on the left side when you hover a block).

Setting `sideMenu={false}` on `BlockNoteView` tells BlockNote not to show the default Block Side Menu.

<div className="nx-mt-6 nx-leading-7 first:nx-mt-0">
<small>
<strong>Tip:</strong> The children you pass to the `SideMenu` component
should be default buttons (e.g. `DragHandleButton`) or custom buttons
(`SideMenuButton`). To see all the components you can use, head to the
[Side Menu's source code](link).
</small>
</div>

## Changing Drag Handle Menu Items

You can also change the items in the Drag Handle Menu. The demo below adds an item that resets the block type to a paragraph.
Expand Down
8 changes: 8 additions & 0 deletions docs/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@
@tailwind components;
@tailwind utilities;
@tailwind variants;

/* Hack needed because the ShadCN Tailwind config overrides the Nextra Tailwind
config. This is a problem because ShadCN relies on CSS variables which are only
scoped to the editor, and are undefined when Nextra components try to use them.
Seems like this only affects border radius in the demos though. */
body {
--radius: 0.5rem;
}
5 changes: 3 additions & 2 deletions examples/01-basic/01-minimal/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView, useCreateBlockNote } from "@blocknote/react";
import "@blocknote/react/style.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";

export default function App() {
// Creates a new editor instance.
Expand Down
9 changes: 6 additions & 3 deletions examples/01-basic/01-minimal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@blocknote/example-minimal",
"description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
"private": true,
"version": "0.12.0",
"version": "0.12.4",
"scripts": {
"start": "vite",
"dev": "vite",
Expand All @@ -11,8 +11,11 @@
"lint": "eslint . --max-warnings 0"
},
"dependencies": {
"@blocknote/core": "^0.12.0",
"@blocknote/react": "^0.12.0",
"@blocknote/core": "^0.12.4",
"@blocknote/react": "^0.12.4",
"@blocknote/ariakit": "^0.12.4",
"@blocknote/mantine": "^0.12.4",
"@blocknote/shadcn": "^0.12.4",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
5 changes: 3 additions & 2 deletions examples/01-basic/02-block-objects/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Block } from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView, useCreateBlockNote } from "@blocknote/react";
import "@blocknote/react/style.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { useState } from "react";

import "./styles.css";
Expand Down
Loading
Loading