diff --git a/.eslintrc.js b/.eslintrc.js index 983f7ae31e..dee0b4c119 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,6 +24,7 @@ module.exports = { }, }, }, + ignorePatterns: ["**/ui/*"], rules: { curly: 1, "import/no-extraneous-dependencies": [ diff --git a/docs/components/pages/landing/hero/DemoEditor.tsx b/docs/components/pages/landing/hero/DemoEditor.tsx index b57d50203f..acb58ee337 100644 --- a/docs/components/pages/landing/hero/DemoEditor.tsx +++ b/docs/components/pages/landing/hero/DemoEditor.tsx @@ -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"; diff --git a/docs/package.json b/docs/package.json index 4970829479..6634864f93 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,6 +11,9 @@ "dependencies": { "@blocknote/core": "^0.12.1", "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "@headlessui/react": "^1.7.18", "@mantine/core": "^7.5.0", "@next/bundle-analyzer": "^14.1.0", diff --git a/docs/pages/docs/quickstart.mdx b/docs/pages/docs/quickstart.mdx index c33ef16616..71b7ea054c 100644 --- a/docs/pages/docs/quickstart.mdx +++ b/docs/pages/docs/quickstart.mdx @@ -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 @@ -26,7 +26,7 @@ With the `useCreateBlockNote` hook, we can create a new editor instance, then us -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). Next.js usage (or other server-side React frameworks) diff --git a/examples/01-basic/01-minimal/App.tsx b/examples/01-basic/01-minimal/App.tsx index 55a0cc8e69..c545b7b4dd 100644 --- a/examples/01-basic/01-minimal/App.tsx +++ b/examples/01-basic/01-minimal/App.tsx @@ -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. diff --git a/examples/01-basic/01-minimal/package.json b/examples/01-basic/01-minimal/package.json index 41993cc9e0..64d0e12aa8 100644 --- a/examples/01-basic/01-minimal/package.json +++ b/examples/01-basic/01-minimal/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/02-block-objects/App.tsx b/examples/01-basic/02-block-objects/App.tsx index 45cd7c39e6..846df5d180 100644 --- a/examples/01-basic/02-block-objects/App.tsx +++ b/examples/01-basic/02-block-objects/App.tsx @@ -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"; diff --git a/examples/01-basic/02-block-objects/package.json b/examples/01-basic/02-block-objects/package.json index 0acac38a6d..81cd70690d 100644 --- a/examples/01-basic/02-block-objects/package.json +++ b/examples/01-basic/02-block-objects/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/03-all-blocks/App.tsx b/examples/01-basic/03-all-blocks/App.tsx index 19758e6017..ff6e4d05bd 100644 --- a/examples/01-basic/03-all-blocks/App.tsx +++ b/examples/01-basic/03-all-blocks/App.tsx @@ -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. diff --git a/examples/01-basic/03-all-blocks/package.json b/examples/01-basic/03-all-blocks/package.json index 39561f0b95..efa243f30e 100644 --- a/examples/01-basic/03-all-blocks/package.json +++ b/examples/01-basic/03-all-blocks/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/04-selection-blocks/App.tsx b/examples/01-basic/04-selection-blocks/App.tsx index 5649a37878..5251754f5a 100644 --- a/examples/01-basic/04-selection-blocks/App.tsx +++ b/examples/01-basic/04-selection-blocks/App.tsx @@ -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"; diff --git a/examples/01-basic/04-selection-blocks/package.json b/examples/01-basic/04-selection-blocks/package.json index e087a6d5ff..a541c96eb2 100644 --- a/examples/01-basic/04-selection-blocks/package.json +++ b/examples/01-basic/04-selection-blocks/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/05-block-manipulation/App.tsx b/examples/01-basic/05-block-manipulation/App.tsx index f961d3527d..412f39c56e 100644 --- a/examples/01-basic/05-block-manipulation/App.tsx +++ b/examples/01-basic/05-block-manipulation/App.tsx @@ -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"; import "./styles.css"; diff --git a/examples/01-basic/05-block-manipulation/package.json b/examples/01-basic/05-block-manipulation/package.json index 9a0b49bbf6..951063ca7b 100644 --- a/examples/01-basic/05-block-manipulation/package.json +++ b/examples/01-basic/05-block-manipulation/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/06-file-uploading/App.tsx b/examples/01-basic/06-file-uploading/App.tsx index c7fea399e8..725c2346a9 100644 --- a/examples/01-basic/06-file-uploading/App.tsx +++ b/examples/01-basic/06-file-uploading/App.tsx @@ -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"; // Uploads a file to tmpfiles.org and returns the URL to the uploaded file. async function uploadFile(file: File) { diff --git a/examples/01-basic/06-file-uploading/package.json b/examples/01-basic/06-file-uploading/package.json index 4d80ea85cb..fc41e7bf39 100644 --- a/examples/01-basic/06-file-uploading/package.json +++ b/examples/01-basic/06-file-uploading/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/07-saving-loading/App.tsx b/examples/01-basic/07-saving-loading/App.tsx index df8a07b99e..5fe11c206b 100644 --- a/examples/01-basic/07-saving-loading/App.tsx +++ b/examples/01-basic/07-saving-loading/App.tsx @@ -1,7 +1,7 @@ import { Block, BlockNoteEditor, PartialBlock } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; -import { BlockNoteView } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { useEffect, useMemo, useState } from "react"; async function saveToStorage(jsonBlocks: Block[]) { diff --git a/examples/01-basic/07-saving-loading/package.json b/examples/01-basic/07-saving-loading/package.json index 927b53a1d9..15446d53a9 100644 --- a/examples/01-basic/07-saving-loading/package.json +++ b/examples/01-basic/07-saving-loading/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/08-shadcn/App.tsx b/examples/01-basic/08-shadcn/App.tsx index c3bf0fdb2b..754b4a5e94 100644 --- a/examples/01-basic/08-shadcn/App.tsx +++ b/examples/01-basic/08-shadcn/App.tsx @@ -1,12 +1,22 @@ import "@blocknote/core/fonts/inter.css"; import { useCreateBlockNote } from "@blocknote/react"; -import "@blocknote/react/style.css"; import { BlockNoteView } from "@blocknote/shadcn"; +import "@blocknote/shadcn/style.css"; export default function App() { // Creates a new editor instance. const editor = useCreateBlockNote(); // Renders the editor instance using a React component. - return ; + return ( + + ); } diff --git a/examples/01-basic/08-shadcn/README.md b/examples/01-basic/08-shadcn/README.md index 9e6a3791ae..3056c8f9a5 100644 --- a/examples/01-basic/08-shadcn/README.md +++ b/examples/01-basic/08-shadcn/README.md @@ -1,6 +1,6 @@ -# Basic Setup TODO +# Use with ShadCN -This example shows the minimal code required to set up a BlockNote editor in React. +This example shows how you can integrate BlockNote with ShadCN, replacing the default Mantine UI with ShadCN components. **Relevant Docs:** diff --git a/examples/01-basic/08-shadcn/index.html b/examples/01-basic/08-shadcn/index.html index 4a44d67d81..c70c418c1a 100644 --- a/examples/01-basic/08-shadcn/index.html +++ b/examples/01-basic/08-shadcn/index.html @@ -5,7 +5,7 @@ - Basic Setup TODO + Use with ShadCN
diff --git a/examples/01-basic/08-shadcn/package.json b/examples/01-basic/08-shadcn/package.json index 0f0acf3a1f..b230f15c03 100644 --- a/examples/01-basic/08-shadcn/package.json +++ b/examples/01-basic/08-shadcn/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/01-basic/09-ariakit/.bnexample.json b/examples/01-basic/09-ariakit/.bnexample.json new file mode 100644 index 0000000000..6d4a02dd52 --- /dev/null +++ b/examples/01-basic/09-ariakit/.bnexample.json @@ -0,0 +1,6 @@ +{ + "playground": true, + "docs": true, + "author": "matthewlipski", + "tags": ["Basic"] +} diff --git a/examples/01-basic/09-ariakit/App.tsx b/examples/01-basic/09-ariakit/App.tsx new file mode 100644 index 0000000000..1a86f6b436 --- /dev/null +++ b/examples/01-basic/09-ariakit/App.tsx @@ -0,0 +1,12 @@ +import "@blocknote/core/fonts/inter.css"; +import { useCreateBlockNote } from "@blocknote/react"; +import { BlockNoteView } from "@blocknote/ariakit"; +import "@blocknote/ariakit/style.css"; + +export default function App() { + // Creates a new editor instance. + const editor = useCreateBlockNote(); + + // Renders the editor instance using a React component. + return ; +} diff --git a/examples/01-basic/09-ariakit/README.md b/examples/01-basic/09-ariakit/README.md new file mode 100644 index 0000000000..50d7787e6a --- /dev/null +++ b/examples/01-basic/09-ariakit/README.md @@ -0,0 +1,7 @@ +# Use with Ariakit + +This example shows how you can integrate BlockNote with Ariakit, replacing the default Mantine UI with Ariakit components. + +**Relevant Docs:** + +- [Editor Setup](/docs/editor-basics/setup) diff --git a/examples/01-basic/09-ariakit/index.html b/examples/01-basic/09-ariakit/index.html new file mode 100644 index 0000000000..f394c4992a --- /dev/null +++ b/examples/01-basic/09-ariakit/index.html @@ -0,0 +1,14 @@ + + + + + + Use with Ariakit + + +
+ + + diff --git a/packages/shadcn/src/main.tsx b/examples/01-basic/09-ariakit/main.tsx similarity index 51% rename from packages/shadcn/src/main.tsx rename to examples/01-basic/09-ariakit/main.tsx index 54a23b9d15..f88b490fbd 100644 --- a/packages/shadcn/src/main.tsx +++ b/examples/01-basic/09-ariakit/main.tsx @@ -1,14 +1,11 @@ +// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY import React from "react"; import { createRoot } from "react-dom/client"; +import App from "./App"; -import { Button } from "./components/ui/button"; -import "./style.css"; const root = createRoot(document.getElementById("root")!); root.render( - + ); diff --git a/examples/01-basic/09-ariakit/package.json b/examples/01-basic/09-ariakit/package.json new file mode 100644 index 0000000000..910ef472df --- /dev/null +++ b/examples/01-basic/09-ariakit/package.json @@ -0,0 +1,37 @@ +{ + "name": "@blocknote/example-ariakit", + "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", + "private": true, + "version": "0.12.0", + "scripts": { + "start": "vite", + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview", + "lint": "eslint . --max-warnings 0" + }, + "dependencies": { + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", + "@vitejs/plugin-react": "^4.0.4", + "eslint": "^8.10.0", + "vite": "^4.4.8" + }, + "eslintConfig": { + "extends": [ + "../../../.eslintrc.js" + ] + }, + "eslintIgnore": [ + "dist" + ] +} \ No newline at end of file diff --git a/examples/01-basic/09-ariakit/tsconfig.json b/examples/01-basic/09-ariakit/tsconfig.json new file mode 100644 index 0000000000..1bd8ab3c57 --- /dev/null +++ b/examples/01-basic/09-ariakit/tsconfig.json @@ -0,0 +1,36 @@ +{ + "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "composite": true + }, + "include": [ + "." + ], + "__ADD_FOR_LOCAL_DEV_references": [ + { + "path": "../../../packages/core/" + }, + { + "path": "../../../packages/react/" + } + ] +} \ No newline at end of file diff --git a/examples/01-basic/09-ariakit/vite.config.ts b/examples/01-basic/09-ariakit/vite.config.ts new file mode 100644 index 0000000000..f62ab20bc2 --- /dev/null +++ b/examples/01-basic/09-ariakit/vite.config.ts @@ -0,0 +1,32 @@ +// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY +import react from "@vitejs/plugin-react"; +import * as fs from "fs"; +import * as path from "path"; +import { defineConfig } from "vite"; +// import eslintPlugin from "vite-plugin-eslint"; +// https://vitejs.dev/config/ +export default defineConfig((conf) => ({ + plugins: [react()], + optimizeDeps: {}, + build: { + sourcemap: true, + }, + resolve: { + alias: + conf.command === "build" || + !fs.existsSync(path.resolve(__dirname, "../../packages/core/src")) + ? {} + : ({ + // Comment out the lines below to load a built version of blocknote + // or, keep as is to load live from sources with live reload working + "@blocknote/core": path.resolve( + __dirname, + "../../packages/core/src/" + ), + "@blocknote/react": path.resolve( + __dirname, + "../../packages/react/src/" + ), + } as any), + }, +})); diff --git a/examples/01-basic/testing/App.tsx b/examples/01-basic/testing/App.tsx index 5bc1b1c47d..de439b5928 100644 --- a/examples/01-basic/testing/App.tsx +++ b/examples/01-basic/testing/App.tsx @@ -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"; export default function App() { // Creates a new editor instance. diff --git a/examples/01-basic/testing/package.json b/examples/01-basic/testing/package.json index 451c22b29e..5109368ec6 100644 --- a/examples/01-basic/testing/package.json +++ b/examples/01-basic/testing/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/02-ui-components/01-ui-elements-remove/App.tsx b/examples/02-ui-components/01-ui-elements-remove/App.tsx index 0f67fdc449..b2f9038ab6 100644 --- a/examples/02-ui-components/01-ui-elements-remove/App.tsx +++ b/examples/02-ui-components/01-ui-elements-remove/App.tsx @@ -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. diff --git a/examples/02-ui-components/01-ui-elements-remove/package.json b/examples/02-ui-components/01-ui-elements-remove/package.json index 01bc2f7fc2..670a9fb53c 100644 --- a/examples/02-ui-components/01-ui-elements-remove/package.json +++ b/examples/02-ui-components/01-ui-elements-remove/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx b/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx index 8f44929e33..779452273d 100644 --- a/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx +++ b/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx @@ -1,7 +1,6 @@ import "@blocknote/core/fonts/inter.css"; import { BasicTextStyleButton, - BlockNoteView, BlockTypeSelect, ColorStyleButton, CreateLinkButton, @@ -14,7 +13,8 @@ import { UnnestBlockButton, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { BlueButton } from "./BlueButton"; diff --git a/examples/02-ui-components/02-formatting-toolbar-buttons/BlueButton.tsx b/examples/02-ui-components/02-formatting-toolbar-buttons/BlueButton.tsx index 4cde53596c..48400a273e 100644 --- a/examples/02-ui-components/02-formatting-toolbar-buttons/BlueButton.tsx +++ b/examples/02-ui-components/02-formatting-toolbar-buttons/BlueButton.tsx @@ -1,14 +1,17 @@ import { - ToolbarButton, useBlockNoteEditor, + useComponentsContext, useEditorContentOrSelectionChange, } from "@blocknote/react"; +import "@blocknote/mantine/style.css"; import { useState } from "react"; // Custom Formatting Toolbar Button to toggle blue text & background color. export function BlueButton() { const editor = useBlockNoteEditor(); + const Components = useComponentsContext()!; + // Tracks whether the text & background are both blue. const [isSelected, setIsSelected] = useState( editor.getActiveStyles().textColor === "blue" && @@ -24,7 +27,7 @@ export function BlueButton() { }, editor); return ( - { editor.toggleStyles({ @@ -34,6 +37,6 @@ export function BlueButton() { }} isSelected={isSelected}> Blue - + ); } diff --git a/examples/02-ui-components/02-formatting-toolbar-buttons/package.json b/examples/02-ui-components/02-formatting-toolbar-buttons/package.json index e4db1b4ba8..49fbb2416e 100644 --- a/examples/02-ui-components/02-formatting-toolbar-buttons/package.json +++ b/examples/02-ui-components/02-formatting-toolbar-buttons/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx b/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx index 0ede58d56e..fce0767f09 100644 --- a/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx +++ b/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx @@ -1,14 +1,14 @@ import { BlockNoteSchema, defaultBlockSpecs } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, + BlockTypeSelectItem, FormattingToolbar, FormattingToolbarController, - useCreateBlockNote, blockTypeSelectItems, - BlockTypeSelectItem, + useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { RiAlertFill } from "react-icons/ri"; import { Alert } from "./Alert"; @@ -56,7 +56,7 @@ export default function App() { formattingToolbar={() => ( + { editor.removeBlocks([props.block]); }} /> - + ); } diff --git a/examples/02-ui-components/04-side-menu-buttons/package.json b/examples/02-ui-components/04-side-menu-buttons/package.json index c5c820c0cb..ff499b2065 100644 --- a/examples/02-ui-components/04-side-menu-buttons/package.json +++ b/examples/02-ui-components/04-side-menu-buttons/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.3.1" diff --git a/examples/02-ui-components/05-side-menu-drag-handle-items/App.tsx b/examples/02-ui-components/05-side-menu-drag-handle-items/App.tsx index 8652837ae1..9f9cb25f57 100644 --- a/examples/02-ui-components/05-side-menu-drag-handle-items/App.tsx +++ b/examples/02-ui-components/05-side-menu-drag-handle-items/App.tsx @@ -1,15 +1,15 @@ import "@blocknote/core/fonts/inter.css"; import { BlockColorsItem, - BlockNoteView, DragHandleMenu, - DragHandleMenuItem, RemoveBlockItem, SideMenu, SideMenuController, + useComponentsContext, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; export default function App() { // Creates a new editor instance. @@ -34,6 +34,8 @@ export default function App() { ], }); + const Components = useComponentsContext()!; + // Renders the editor instance. return ( @@ -46,12 +48,12 @@ export default function App() { Delete Colors {/* Item which resets the hovered block's type. */} - { editor.updateBlock(props.block, { type: "paragraph" }); }}> Reset Type - + )} /> diff --git a/examples/02-ui-components/05-side-menu-drag-handle-items/package.json b/examples/02-ui-components/05-side-menu-drag-handle-items/package.json index 9982ce078e..0b8deb595b 100644 --- a/examples/02-ui-components/05-side-menu-drag-handle-items/package.json +++ b/examples/02-ui-components/05-side-menu-drag-handle-items/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.3.1" diff --git a/examples/02-ui-components/06-suggestion-menus-slash-menu-items/App.tsx b/examples/02-ui-components/06-suggestion-menus-slash-menu-items/App.tsx index bc2900fbec..984cf3d4e1 100644 --- a/examples/02-ui-components/06-suggestion-menus-slash-menu-items/App.tsx +++ b/examples/02-ui-components/06-suggestion-menus-slash-menu-items/App.tsx @@ -5,13 +5,13 @@ import { } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, DefaultReactSuggestionItem, getDefaultReactSlashMenuItems, SuggestionMenuController, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { HiOutlineGlobeAlt } from "react-icons/hi"; // Custom Slash Menu item to insert a block after the current one. diff --git a/examples/02-ui-components/06-suggestion-menus-slash-menu-items/package.json b/examples/02-ui-components/06-suggestion-menus-slash-menu-items/package.json index 87a8b55798..19e88c8643 100644 --- a/examples/02-ui-components/06-suggestion-menus-slash-menu-items/package.json +++ b/examples/02-ui-components/06-suggestion-menus-slash-menu-items/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.3.1" diff --git a/examples/02-ui-components/07-suggestion-menus-slash-menu-component/App.tsx b/examples/02-ui-components/07-suggestion-menus-slash-menu-component/App.tsx index fdf1137fa7..2bd26465f0 100644 --- a/examples/02-ui-components/07-suggestion-menus-slash-menu-component/App.tsx +++ b/examples/02-ui-components/07-suggestion-menus-slash-menu-component/App.tsx @@ -1,12 +1,12 @@ import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, DefaultReactSuggestionItem, SuggestionMenuController, SuggestionMenuProps, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import "./styles.css"; diff --git a/examples/02-ui-components/07-suggestion-menus-slash-menu-component/package.json b/examples/02-ui-components/07-suggestion-menus-slash-menu-component/package.json index 7eb92b487a..ca1f8ed468 100644 --- a/examples/02-ui-components/07-suggestion-menus-slash-menu-component/package.json +++ b/examples/02-ui-components/07-suggestion-menus-slash-menu-component/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/02-ui-components/08-custom-ui/App.tsx b/examples/02-ui-components/08-custom-ui/App.tsx index b447f7aefa..f3bb61a09f 100644 --- a/examples/02-ui-components/08-custom-ui/App.tsx +++ b/examples/02-ui-components/08-custom-ui/App.tsx @@ -1,13 +1,13 @@ import { filterSuggestionItems } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, getDefaultReactSlashMenuItems, SideMenuController, SuggestionMenuController, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { CustomFormattingToolbar } from "./CustomFormattingToolbar"; import { CustomSideMenu } from "./CustomSideMenu"; diff --git a/examples/02-ui-components/08-custom-ui/package.json b/examples/02-ui-components/08-custom-ui/package.json index 1a7a5bd426..ab13494420 100644 --- a/examples/02-ui-components/08-custom-ui/package.json +++ b/examples/02-ui-components/08-custom-ui/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "@mantine/core": "^7.5.0", diff --git a/examples/02-ui-components/link-toolbar-buttons/AlertButton.tsx b/examples/02-ui-components/link-toolbar-buttons/AlertButton.tsx index 123d856b0e..b393d6077e 100644 --- a/examples/02-ui-components/link-toolbar-buttons/AlertButton.tsx +++ b/examples/02-ui-components/link-toolbar-buttons/AlertButton.tsx @@ -1,14 +1,16 @@ -import { LinkToolbarProps, ToolbarButton } from "@blocknote/react"; +import { LinkToolbarProps, useComponentsContext } from "@blocknote/react"; // Custom Link Toolbar button to open a browser alert. export function AlertButton(props: LinkToolbarProps) { + const Components = useComponentsContext()!; + return ( - { window.alert(`Link URL: ${props.url}`); }}> Open Alert - + ); } diff --git a/examples/02-ui-components/link-toolbar-buttons/App.tsx b/examples/02-ui-components/link-toolbar-buttons/App.tsx index 1e4525bd72..4664d4bf28 100644 --- a/examples/02-ui-components/link-toolbar-buttons/App.tsx +++ b/examples/02-ui-components/link-toolbar-buttons/App.tsx @@ -1,11 +1,11 @@ import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, LinkToolbar, LinkToolbarController, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { AlertButton } from "./AlertButton"; diff --git a/examples/02-ui-components/link-toolbar-buttons/package.json b/examples/02-ui-components/link-toolbar-buttons/package.json index 470ec0c68f..4f73d483cc 100644 --- a/examples/02-ui-components/link-toolbar-buttons/package.json +++ b/examples/02-ui-components/link-toolbar-buttons/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/03-theming/01-theming-dom-attributes/App.tsx b/examples/03-theming/01-theming-dom-attributes/App.tsx index 5f5aa61cc9..7068e12388 100644 --- a/examples/03-theming/01-theming-dom-attributes/App.tsx +++ b/examples/03-theming/01-theming-dom-attributes/App.tsx @@ -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"; import "./styles.css"; diff --git a/examples/03-theming/01-theming-dom-attributes/package.json b/examples/03-theming/01-theming-dom-attributes/package.json index d747c5a61e..b0d1bce695 100644 --- a/examples/03-theming/01-theming-dom-attributes/package.json +++ b/examples/03-theming/01-theming-dom-attributes/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/03-theming/02-changing-font/App.tsx b/examples/03-theming/02-changing-font/App.tsx index e21dd05893..4ef3f9a3dd 100644 --- a/examples/03-theming/02-changing-font/App.tsx +++ b/examples/03-theming/02-changing-font/App.tsx @@ -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"; import "./styles.css"; diff --git a/examples/03-theming/02-changing-font/package.json b/examples/03-theming/02-changing-font/package.json index ba4a149a7f..47fb985f7b 100644 --- a/examples/03-theming/02-changing-font/package.json +++ b/examples/03-theming/02-changing-font/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/03-theming/03-theming-css/App.tsx b/examples/03-theming/03-theming-css/App.tsx index 7a65b64349..493ae7d4ed 100644 --- a/examples/03-theming/03-theming-css/App.tsx +++ b/examples/03-theming/03-theming-css/App.tsx @@ -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"; import "./styles.css"; diff --git a/examples/03-theming/03-theming-css/package.json b/examples/03-theming/03-theming-css/package.json index ff356edda6..1f5cd62303 100644 --- a/examples/03-theming/03-theming-css/package.json +++ b/examples/03-theming/03-theming-css/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/03-theming/04-theming-css-variables/App.tsx b/examples/03-theming/04-theming-css-variables/App.tsx index dcfc1a4a72..ba45053f04 100644 --- a/examples/03-theming/04-theming-css-variables/App.tsx +++ b/examples/03-theming/04-theming-css-variables/App.tsx @@ -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"; import "./styles.css"; diff --git a/examples/03-theming/04-theming-css-variables/package.json b/examples/03-theming/04-theming-css-variables/package.json index c4a0335626..8a0c9f9822 100644 --- a/examples/03-theming/04-theming-css-variables/package.json +++ b/examples/03-theming/04-theming-css-variables/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/03-theming/05-theming-css-variables-code/App.tsx b/examples/03-theming/05-theming-css-variables-code/App.tsx index 0f8e944d32..e26239b446 100644 --- a/examples/03-theming/05-theming-css-variables-code/App.tsx +++ b/examples/03-theming/05-theming-css-variables-code/App.tsx @@ -1,12 +1,12 @@ import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, darkDefaultTheme, lightDefaultTheme, Theme, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; // Base theme const lightRedTheme = { diff --git a/examples/03-theming/05-theming-css-variables-code/package.json b/examples/03-theming/05-theming-css-variables-code/package.json index 27c24dc2a0..ea4f2ab4be 100644 --- a/examples/03-theming/05-theming-css-variables-code/package.json +++ b/examples/03-theming/05-theming-css-variables-code/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/04-interoperability/01-converting-blocks-to-html/App.tsx b/examples/04-interoperability/01-converting-blocks-to-html/App.tsx index 698de6f48e..e10fe0c57f 100644 --- a/examples/04-interoperability/01-converting-blocks-to-html/App.tsx +++ b/examples/04-interoperability/01-converting-blocks-to-html/App.tsx @@ -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"; import { useState } from "react"; import "./styles.css"; diff --git a/examples/04-interoperability/01-converting-blocks-to-html/package.json b/examples/04-interoperability/01-converting-blocks-to-html/package.json index 49508d72f5..4050c9240b 100644 --- a/examples/04-interoperability/01-converting-blocks-to-html/package.json +++ b/examples/04-interoperability/01-converting-blocks-to-html/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/04-interoperability/02-converting-blocks-from-html/App.tsx b/examples/04-interoperability/02-converting-blocks-from-html/App.tsx index 98af0279b5..8b53b5ac9c 100644 --- a/examples/04-interoperability/02-converting-blocks-from-html/App.tsx +++ b/examples/04-interoperability/02-converting-blocks-from-html/App.tsx @@ -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"; import { ChangeEvent, useCallback, useEffect } from "react"; import "./styles.css"; diff --git a/examples/04-interoperability/02-converting-blocks-from-html/package.json b/examples/04-interoperability/02-converting-blocks-from-html/package.json index ec274231e4..028c64d0e4 100644 --- a/examples/04-interoperability/02-converting-blocks-from-html/package.json +++ b/examples/04-interoperability/02-converting-blocks-from-html/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/04-interoperability/03-converting-blocks-to-md/App.tsx b/examples/04-interoperability/03-converting-blocks-to-md/App.tsx index 1e020bfae7..c51a3ac92e 100644 --- a/examples/04-interoperability/03-converting-blocks-to-md/App.tsx +++ b/examples/04-interoperability/03-converting-blocks-to-md/App.tsx @@ -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"; import { useState } from "react"; import "./styles.css"; diff --git a/examples/04-interoperability/03-converting-blocks-to-md/package.json b/examples/04-interoperability/03-converting-blocks-to-md/package.json index b57907e8cc..b543beab0c 100644 --- a/examples/04-interoperability/03-converting-blocks-to-md/package.json +++ b/examples/04-interoperability/03-converting-blocks-to-md/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/04-interoperability/04-converting-blocks-from-md/App.tsx b/examples/04-interoperability/04-converting-blocks-from-md/App.tsx index 3015c30f9d..876f5573e9 100644 --- a/examples/04-interoperability/04-converting-blocks-from-md/App.tsx +++ b/examples/04-interoperability/04-converting-blocks-from-md/App.tsx @@ -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"; import { ChangeEvent, useCallback, useEffect } from "react"; const initialMarkdown = "Hello, **world!**"; diff --git a/examples/04-interoperability/04-converting-blocks-from-md/package.json b/examples/04-interoperability/04-converting-blocks-from-md/package.json index a1e6d389d8..47a5cca23a 100644 --- a/examples/04-interoperability/04-converting-blocks-from-md/package.json +++ b/examples/04-interoperability/04-converting-blocks-from-md/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/05-custom-schema/01-alert-block/App.tsx b/examples/05-custom-schema/01-alert-block/App.tsx index 0dda8fbe61..dcaefdfbdf 100644 --- a/examples/05-custom-schema/01-alert-block/App.tsx +++ b/examples/05-custom-schema/01-alert-block/App.tsx @@ -6,12 +6,12 @@ import { } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, SuggestionMenuController, getDefaultReactSlashMenuItems, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { RiAlertFill } from "react-icons/ri"; import { Alert } from "./Alert"; diff --git a/examples/05-custom-schema/01-alert-block/package.json b/examples/05-custom-schema/01-alert-block/package.json index ed10f99da7..d267e6cc88 100644 --- a/examples/05-custom-schema/01-alert-block/package.json +++ b/examples/05-custom-schema/01-alert-block/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "@mantine/core": "^7.5.0", diff --git a/examples/05-custom-schema/02-suggestion-menus-mentions/App.tsx b/examples/05-custom-schema/02-suggestion-menus-mentions/App.tsx index d3f0463537..e86e4594e9 100644 --- a/examples/05-custom-schema/02-suggestion-menus-mentions/App.tsx +++ b/examples/05-custom-schema/02-suggestion-menus-mentions/App.tsx @@ -5,12 +5,12 @@ import { } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, DefaultReactSuggestionItem, SuggestionMenuController, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { Mention } from "./Mention"; diff --git a/examples/05-custom-schema/02-suggestion-menus-mentions/package.json b/examples/05-custom-schema/02-suggestion-menus-mentions/package.json index d8c980f452..e5324faf07 100644 --- a/examples/05-custom-schema/02-suggestion-menus-mentions/package.json +++ b/examples/05-custom-schema/02-suggestion-menus-mentions/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/05-custom-schema/03-font-style/App.tsx b/examples/05-custom-schema/03-font-style/App.tsx index edb7f96322..0035fc1bbb 100644 --- a/examples/05-custom-schema/03-font-style/App.tsx +++ b/examples/05-custom-schema/03-font-style/App.tsx @@ -2,7 +2,6 @@ import { BlockNoteSchema, defaultStyleSpecs } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { BasicTextStyleButton, - BlockNoteView, BlockTypeSelect, ColorStyleButton, CreateLinkButton, @@ -12,12 +11,13 @@ import { NestBlockButton, ReplaceImageButton, TextAlignButton, - ToolbarButton, UnnestBlockButton, useBlockNoteEditor, + useComponentsContext, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { RiText } from "react-icons/ri"; import { Font } from "./Font"; @@ -41,10 +41,12 @@ const SetFontStyleButton = () => { typeof schema.styleSchema >(); + const Components = useComponentsContext()!; + return ( - } onClick={() => { const fontName = prompt("Enter a font name") || "Comic Sans MS"; diff --git a/examples/05-custom-schema/03-font-style/package.json b/examples/05-custom-schema/03-font-style/package.json index f00fab3dee..29fa2ae516 100644 --- a/examples/05-custom-schema/03-font-style/package.json +++ b/examples/05-custom-schema/03-font-style/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/05-custom-schema/react-custom-blocks/App.tsx b/examples/05-custom-schema/react-custom-blocks/App.tsx index 49a541a21c..f92ffb7be6 100644 --- a/examples/05-custom-schema/react-custom-blocks/App.tsx +++ b/examples/05-custom-schema/react-custom-blocks/App.tsx @@ -4,12 +4,9 @@ import { defaultProps, } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; -import { - BlockNoteView, - createReactBlockSpec, - useCreateBlockNote, -} from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { createReactBlockSpec, useCreateBlockNote } from "@blocknote/react"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import "./styles.css"; diff --git a/examples/05-custom-schema/react-custom-blocks/package.json b/examples/05-custom-schema/react-custom-blocks/package.json index c76019d6ce..e4ec269d8b 100644 --- a/examples/05-custom-schema/react-custom-blocks/package.json +++ b/examples/05-custom-schema/react-custom-blocks/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/05-custom-schema/react-custom-inline-content/App.tsx b/examples/05-custom-schema/react-custom-inline-content/App.tsx index e321420646..54f0ff7251 100644 --- a/examples/05-custom-schema/react-custom-inline-content/App.tsx +++ b/examples/05-custom-schema/react-custom-inline-content/App.tsx @@ -1,11 +1,11 @@ import { BlockNoteSchema, defaultInlineContentSpecs } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, createReactInlineContentSpec, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; const mention = createReactInlineContentSpec( { diff --git a/examples/05-custom-schema/react-custom-inline-content/package.json b/examples/05-custom-schema/react-custom-inline-content/package.json index 0122e6fd86..00d6e21fd1 100644 --- a/examples/05-custom-schema/react-custom-inline-content/package.json +++ b/examples/05-custom-schema/react-custom-inline-content/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/05-custom-schema/react-custom-styles/App.tsx b/examples/05-custom-schema/react-custom-styles/App.tsx index aba31bdeda..f19533c79d 100644 --- a/examples/05-custom-schema/react-custom-styles/App.tsx +++ b/examples/05-custom-schema/react-custom-styles/App.tsx @@ -1,17 +1,17 @@ import { BlockNoteSchema, defaultStyleSpecs } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, createReactStyleSpec, FormattingToolbar, FormattingToolbarController, FormattingToolbarProps, - ToolbarButton, useActiveStyles, useBlockNoteEditor, + useComponentsContext, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; const small = createReactStyleSpec( { @@ -51,9 +51,11 @@ const CustomFormattingToolbar = (props: FormattingToolbarProps) => { const editor = useBlockNoteEditor(schema); const activeStyles = useActiveStyles(editor); + const Components = useComponentsContext()!; + return ( - { editor.toggleStyles({ @@ -62,8 +64,8 @@ const CustomFormattingToolbar = (props: FormattingToolbarProps) => { }} isSelected={activeStyles.small}> Small - - + { editor.toggleStyles({ @@ -72,7 +74,7 @@ const CustomFormattingToolbar = (props: FormattingToolbarProps) => { }} isSelected={!!activeStyles.fontSize}> Font size - + ); }; diff --git a/examples/05-custom-schema/react-custom-styles/package.json b/examples/05-custom-schema/react-custom-styles/package.json index 327acc839d..f42a5173bf 100644 --- a/examples/05-custom-schema/react-custom-styles/package.json +++ b/examples/05-custom-schema/react-custom-styles/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/06-collaboration/01-partykit/App.tsx b/examples/06-collaboration/01-partykit/App.tsx index 5d0e98fb51..cecfb6767e 100644 --- a/examples/06-collaboration/01-partykit/App.tsx +++ b/examples/06-collaboration/01-partykit/App.tsx @@ -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"; import YPartyKitProvider from "y-partykit/provider"; import * as Y from "yjs"; diff --git a/examples/06-collaboration/01-partykit/package.json b/examples/06-collaboration/01-partykit/package.json index 983e97f256..36d35456ef 100644 --- a/examples/06-collaboration/01-partykit/package.json +++ b/examples/06-collaboration/01-partykit/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "y-partykit": "^0.0.25", diff --git a/examples/06-collaboration/02-liveblocks/App.tsx b/examples/06-collaboration/02-liveblocks/App.tsx index cc65e59863..854b6b1091 100644 --- a/examples/06-collaboration/02-liveblocks/App.tsx +++ b/examples/06-collaboration/02-liveblocks/App.tsx @@ -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"; import { createClient } from "@liveblocks/client"; import LiveblocksProvider from "@liveblocks/yjs"; import * as Y from "yjs"; diff --git a/examples/06-collaboration/02-liveblocks/package.json b/examples/06-collaboration/02-liveblocks/package.json index 992c95c466..1369a4bba3 100644 --- a/examples/06-collaboration/02-liveblocks/package.json +++ b/examples/06-collaboration/02-liveblocks/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "@liveblocks/client": "^1.10.0", diff --git a/examples/vanilla-js/react-vanilla-custom-blocks/App.tsx b/examples/vanilla-js/react-vanilla-custom-blocks/App.tsx index 6be9d75827..c0dbb42ce8 100644 --- a/examples/vanilla-js/react-vanilla-custom-blocks/App.tsx +++ b/examples/vanilla-js/react-vanilla-custom-blocks/App.tsx @@ -5,8 +5,9 @@ import { defaultProps, } 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 "./styles.css"; diff --git a/examples/vanilla-js/react-vanilla-custom-blocks/package.json b/examples/vanilla-js/react-vanilla-custom-blocks/package.json index 618db40ffe..02e835fda1 100644 --- a/examples/vanilla-js/react-vanilla-custom-blocks/package.json +++ b/examples/vanilla-js/react-vanilla-custom-blocks/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/vanilla-js/react-vanilla-custom-inline-content/App.tsx b/examples/vanilla-js/react-vanilla-custom-inline-content/App.tsx index a090f2aa00..7e81477387 100644 --- a/examples/vanilla-js/react-vanilla-custom-inline-content/App.tsx +++ b/examples/vanilla-js/react-vanilla-custom-inline-content/App.tsx @@ -4,8 +4,9 @@ import { defaultInlineContentSpecs, } 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"; const mention = createInlineContentSpec( { diff --git a/examples/vanilla-js/react-vanilla-custom-inline-content/package.json b/examples/vanilla-js/react-vanilla-custom-inline-content/package.json index 83d07b6eb4..b8de3757a2 100644 --- a/examples/vanilla-js/react-vanilla-custom-inline-content/package.json +++ b/examples/vanilla-js/react-vanilla-custom-inline-content/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/examples/vanilla-js/react-vanilla-custom-styles/App.tsx b/examples/vanilla-js/react-vanilla-custom-styles/App.tsx index ee30b7b8ef..813952cda7 100644 --- a/examples/vanilla-js/react-vanilla-custom-styles/App.tsx +++ b/examples/vanilla-js/react-vanilla-custom-styles/App.tsx @@ -5,16 +5,16 @@ import { } from "@blocknote/core"; import "@blocknote/core/fonts/inter.css"; import { - BlockNoteView, FormattingToolbar, FormattingToolbarController, FormattingToolbarProps, - ToolbarButton, useActiveStyles, useBlockNoteEditor, + useComponentsContext, useCreateBlockNote, } from "@blocknote/react"; -import "@blocknote/react/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; const small = createStyleSpec( { @@ -63,9 +63,11 @@ const CustomFormattingToolbar = (props: FormattingToolbarProps) => { const editor = useBlockNoteEditor(schema); const activeStyles = useActiveStyles(editor); + const Components = useComponentsContext()!; + return ( - { editor.toggleStyles({ @@ -74,8 +76,8 @@ const CustomFormattingToolbar = (props: FormattingToolbarProps) => { }} isSelected={activeStyles.small}> Small - - + { editor.toggleStyles({ @@ -84,7 +86,7 @@ const CustomFormattingToolbar = (props: FormattingToolbarProps) => { }} isSelected={!!activeStyles.fontSize}> Font size - + ); }; diff --git a/examples/vanilla-js/react-vanilla-custom-styles/package.json b/examples/vanilla-js/react-vanilla-custom-styles/package.json index d6cb5a2f53..7d01c3f5b2 100644 --- a/examples/vanilla-js/react-vanilla-custom-styles/package.json +++ b/examples/vanilla-js/react-vanilla-custom-styles/package.json @@ -11,8 +11,11 @@ "lint": "eslint . --max-warnings 0" }, "dependencies": { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/package-lock.json b/package-lock.json index 2a71ba0847..153a4fcbbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,11 @@ "docs": { "version": "0.12.2", "dependencies": { + "@blocknote/ariakit": "^0.12.2", "@blocknote/core": "^0.12.1", + "@blocknote/mantine": "^0.12.2", "@blocknote/react": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "@headlessui/react": "^1.7.18", "@mantine/core": "^7.5.0", "@next/bundle-analyzer": "^14.1.0", @@ -2361,6 +2364,10 @@ "node": ">=6.9.0" } }, + "node_modules/@blocknote/ariakit": { + "resolved": "packages/ariakit", + "link": true + }, "node_modules/@blocknote/core": { "resolved": "packages/core", "link": true @@ -2373,6 +2380,10 @@ "resolved": "playground", "link": true }, + "node_modules/@blocknote/mantine": { + "resolved": "packages/mantine", + "link": true + }, "node_modules/@blocknote/react": { "resolved": "packages/react", "link": true @@ -2934,6 +2945,14 @@ "react-dom": "^16 || ^17 || ^18" } }, + "node_modules/@hookform/resolvers": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz", + "integrity": "sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.13", "dev": true, @@ -5147,6 +5166,29 @@ } } }, + "node_modules/@radix-ui/react-label": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", + "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-menu": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz", @@ -5211,6 +5253,67 @@ } } }, + "node_modules/@radix-ui/react-popover": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz", + "integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz", @@ -10986,7 +11089,6 @@ }, "node_modules/fraction.js": { "version": "4.3.7", - "dev": true, "license": "MIT", "engines": { "node": "*" @@ -16005,7 +16107,6 @@ }, "node_modules/normalize-range": { "version": "0.1.2", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -18539,6 +18640,22 @@ "react": ">=16.3.0" } }, + "node_modules/react-hook-form": { + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.2.tgz", + "integrity": "sha512-y++lwaWjtzDt/XNnyGDQy6goHskFualmDlf+jzEZvjvz6KWDf7EboL7pUvRCzPTJd0EOPpdekYaQLEvvG6m6HA==", + "peer": true, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-icons": { "version": "4.12.0", "license": "MIT", @@ -20786,11 +20903,11 @@ "license": "MIT" }, "node_modules/tailwind-merge": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.2.tgz", - "integrity": "sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz", + "integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==", "dependencies": { - "@babel/runtime": "^7.24.0" + "@babel/runtime": "^7.24.1" }, "funding": { "type": "github", @@ -22956,7 +23073,8 @@ }, "node_modules/zod": { "version": "3.22.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -22969,6 +23087,53 @@ "url": "https://github.com/sponsors/wooorm" } }, + "packages/ariakit": { + "name": "@blocknote/ariakit", + "version": "0.12.2", + "license": "MPL-2.0", + "dependencies": { + "@ariakit/react": "^0.4.3", + "@blocknote/core": "*", + "@blocknote/react": "*", + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", + "@vitejs/plugin-react": "^4.0.4", + "eslint": "^8.10.0", + "prettier": "^2.7.1", + "rimraf": "^5.0.5", + "rollup-plugin-webpack-stats": "^0.2.2", + "typescript": "^5.3.3", + "vite": "^4.4.8", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-externalize-deps": "^0.7.0" + }, + "peerDependencies": { + "react": "^18", + "react-dom": "^18" + } + }, + "packages/ariakit/node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/core": { "name": "@blocknote/core", "version": "0.12.1", @@ -23081,17 +23246,63 @@ "typescript": "^5.3.3" } }, + "packages/mantine": { + "name": "@blocknote/mantine", + "version": "0.12.2", + "license": "MPL-2.0", + "dependencies": { + "@blocknote/core": "*", + "@blocknote/react": "*", + "@mantine/core": "^7.5.0", + "@mantine/hooks": "^7.5.0", + "@mantine/utils": "^6.0.21", + "react": "^18", + "react-dom": "^18", + "react-icons": "^4.3.1" + }, + "devDependencies": { + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", + "@vitejs/plugin-react": "^4.0.4", + "eslint": "^8.10.0", + "prettier": "^2.7.1", + "rimraf": "^5.0.5", + "rollup-plugin-webpack-stats": "^0.2.2", + "typescript": "^5.3.3", + "vite": "^4.4.8", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-externalize-deps": "^0.7.0" + }, + "peerDependencies": { + "react": "^18", + "react-dom": "^18" + } + }, + "packages/mantine/node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/react": { "name": "@blocknote/react", "version": "0.12.2", "license": "MPL-2.0", "dependencies": { - "@ariakit/react": "^0.4.3", "@blocknote/core": "^0.12.1", "@floating-ui/react": "^0.26.4", - "@mantine/core": "^7.5.0", - "@mantine/hooks": "^7.5.0", - "@mantine/utils": "^6.0.21", "@tiptap/core": "^2.0.3", "@tiptap/react": "^2.0.3", "lodash.merge": "^4.6.2", @@ -23146,22 +23357,31 @@ "dependencies": { "@blocknote/core": "*", "@blocknote/react": "*", + "@hookform/resolvers": "^3.3.4", "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", + "autoprefixer": "^10.4.19", "class-variance-authority": "^0.7.0", - "clsx": "^2.1.0", + "clsx": "^2.1.1", "lucide-react": "^0.362.0", + "postcss": "^8.4.38", "react": "^18", "react-dom": "^18", - "tailwind-merge": "^2.2.2", - "tailwindcss-animate": "^1.0.7" + "react-hook-form": "^7.51.3", + "tailwind-merge": "^2.3.0", + "tailwindcss": "^3.4.3", + "tailwindcss-animate": "^1.0.7", + "zod": "^3.22.4" }, "devDependencies": { "@radix-ui/colors": "^3.0.0", + "@types/node": "^20.12.7", "@types/react": "^18.0.25", "@types/react-dom": "^18.0.9", "@vitejs/plugin-react": "^4.0.4", @@ -23172,22 +23392,163 @@ "typescript": "^5.3.3", "vite": "^4.4.8", "vite-plugin-eslint": "^1.8.1", - "vite-plugin-externalize-deps": "^0.7.0", - "vitest": "^0.34.1" + "vite-plugin-externalize-deps": "^0.7.0" }, "peerDependencies": { "react": "^18", "react-dom": "^18" } }, + "packages/shadcn/node_modules/@types/node": { + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "packages/shadcn/node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "packages/shadcn/node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "packages/shadcn/node_modules/caniuse-lite": { + "version": "1.0.30001614", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", + "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "packages/shadcn/node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } }, + "packages/shadcn/node_modules/electron-to-chromium": { + "version": "1.4.751", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.751.tgz", + "integrity": "sha512-2DEPi++qa89SMGRhufWTiLmzqyuGmNF3SK4+PQetW1JKiZdEpF4XQonJXJCzyuYSA6mauiMhbyVhqYAP45Hvfw==" + }, + "packages/shadcn/node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "packages/shadcn/node_modules/react-hook-form": { + "version": "7.51.3", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.3.tgz", + "integrity": "sha512-cvJ/wbHdhYx8aviSWh28w9ImjmVsb5Y05n1+FW786vEZQJV5STNM0pW6ujS+oiBecb0ARBxJFyAnXj9+GHXACQ==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "packages/shadcn/node_modules/rimraf": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", @@ -23206,6 +23567,50 @@ "url": "https://github.com/sponsors/isaacs" } }, + "packages/shadcn/node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "packages/shadcn/node_modules/tailwindcss": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", + "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "playground": { "name": "@blocknote/example-editor", "version": "0.12.2", @@ -23258,8 +23663,11 @@ "react-dom": "^18.2.0" }, "devDependencies": { + "@blocknote/ariakit": "^0.12.2", "@blocknote/core": "^0.12.1", + "@blocknote/mantine": "^0.12.2", "@blocknote/react": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", "@playwright/experimental-ct-react": "^1.42.1", "@playwright/test": "^1.42.1", "eslint": "^8.10.0", diff --git a/packages/ariakit/package.json b/packages/ariakit/package.json new file mode 100644 index 0000000000..9c8413ec15 --- /dev/null +++ b/packages/ariakit/package.json @@ -0,0 +1,83 @@ +{ + "name": "@blocknote/ariakit", + "homepage": "https://github.com/TypeCellOS/BlockNote", + "private": false, + "license": "MPL-2.0", + "version": "0.12.2", + "files": [ + "dist", + "types", + "src" + ], + "keywords": [ + "react", + "javascript", + "editor", + "typescript", + "prosemirror", + "wysiwyg", + "rich-text-editor", + "notion", + "yjs", + "block-based", + "tiptap" + ], + "description": "A \"Notion-style\" block-based extensible text editor built on top of Prosemirror and Tiptap.", + "type": "module", + "source": "src/index.tsx", + "types": "./types/src/index.d.ts", + "main": "./dist/blocknote-ariakit.umd.cjs", + "module": "./dist/blocknote-ariakit.js", + "exports": { + ".": { + "types": "./types/src/index.d.ts", + "import": "./dist/blocknote-ariakit.js", + "require": "./dist/blocknote-ariakit.umd.cjs" + }, + "./style.css": { + "import": "./dist/style.css", + "require": "./dist/style.css" + } + }, + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "build-bundled": "tsc && vite build --config vite.config.bundled.ts && git checkout tmp-releases && rm -rf ../../release && mv ../../release-tmp ../../release", + "preview": "vite preview", + "lint": "eslint src --max-warnings 0", + "clean": "rimraf dist && rimraf types" + }, + "dependencies": { + "@ariakit/react": "^0.4.3", + "@blocknote/core": "*", + "@blocknote/react": "*", + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", + "@vitejs/plugin-react": "^4.0.4", + "eslint": "^8.10.0", + "prettier": "^2.7.1", + "rimraf": "^5.0.5", + "rollup-plugin-webpack-stats": "^0.2.2", + "typescript": "^5.3.3", + "vite": "^4.4.8", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-externalize-deps": "^0.7.0" + }, + "peerDependencies": { + "react": "^18", + "react-dom": "^18" + }, + "eslintConfig": { + "extends": [ + "../../.eslintrc.js" + ] + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + } +} diff --git a/packages/ariakit/src/ariakitStyles.css b/packages/ariakit/src/ariakitStyles.css new file mode 100644 index 0000000000..7ff878e3b5 --- /dev/null +++ b/packages/ariakit/src/ariakitStyles.css @@ -0,0 +1,964 @@ +/* This file contains styles copied directly from Ariakit's website, and is +responsible for the majority of the styling. */ + +/* https://ariakit.org/examples/menu-nested */ +.bn-ak-button { + --border: rgb(0 0 0/13%); + --highlight: rgb(255 255 255/20%); + --shadow: rgb(0 0 0/10%); + display: flex; + height: 2.5rem; + user-select: none; + align-items: center; + justify-content: center; + gap: 0.25rem; + white-space: nowrap; + border-radius: 0.5rem; + border-style: none; + background-color: hsl(204 20% 100%); + padding-left: 1rem; + padding-right: 1rem; + font-size: 1rem; + line-height: 1.5rem; + color: hsl(204 4% 0%); + text-decoration-line: none; + outline-width: 2px; + outline-offset: 2px; + outline-color: hsl(204 100% 40%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--highlight), + inset 0 -1px 0 var(--shadow), + 0 1px 1px var(--shadow); + font-weight: 500; +} + +.bn-ak-button:where(.dark, .dark *) { + --border: rgb(255 255 255/10%); + --highlight: rgb(255 255 255/5%); + --shadow: rgb(0 0 0/25%); + background-color: hsl(204 20% 100% / 0.05); + color: hsl(204 20% 100%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 -1px 0 1px var(--shadow), + inset 0 1px 0 var(--highlight); +} + +.bn-ak-button:not(:active):hover { + --border: rgb(0 0 0/33%); +} + +.bn-ak-button:where(.dark, .dark *):not(:active):hover { + --border: rgb(255 255 255/25%); +} + +.bn-ak-button[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-button[data-focus-visible] { + outline-style: solid; +} + +.bn-ak-button:active, +.bn-ak-button[data-active] { + padding-top: 0.125rem; + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--border); +} + +@media (min-width: 640px) { + .bn-ak-button { + gap: 0.5rem; + } +} + +.bn-ak-button:active:where(.dark, .dark *), +.bn-ak-button[data-active]:where(.dark, .dark *) { + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 1px 1px 1px var(--shadow); +} + +.bn-ak-menu { + position: relative; + z-index: 50; + display: flex; + max-height: var(--popover-available-height); + min-width: 180px; + flex-direction: column; + overscroll-behavior: contain; + border-radius: 0.5rem; + border-width: 1px; + border-style: solid; + border-color: hsl(204 20% 88%); + background-color: hsl(204 20% 100%); + padding: 0.5rem; + color: hsl(204 4% 0%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); + outline: none !important; + overflow: visible; +} + +.bn-ak-menu:where(.dark, .dark *) { + border-color: hsl(204 4% 24%); + background-color: hsl(204 4% 16%); + color: hsl(204 20% 100%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.25), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +.bn-ak-menu-item { + display: flex; + cursor: default; + scroll-margin: 0.5rem; + align-items: center; + gap: 0.5rem; + border-radius: 0.25rem; + padding: 0.5rem; + outline: none !important; +} + +.bn-ak-menu-item[aria-disabled="true"] { + opacity: 0.25; +} + +.bn-ak-menu-item[data-active-item] { + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); +} + +.bn-ak-menu-item:active, +.bn-ak-menu-item[data-active] { + background-color: hsl(204 100% 32%); + padding-top: 9px; + padding-bottom: 7px; +} + +.bn-ak-menu:not(:focus) .bn-ak-menu-item:not(:focus)[aria-expanded="true"] { + background-color: hsl(204 4% 0% / 7.5%); + color: currentColor; +} + +.bn-ak-menu:not(:focus) +.bn-ak-menu-item:not(:focus)[aria-expanded="true"]:where(.dark, .dark *) { + background-color: hsl(204 20% 100% / 0.1); +} + +.bn-ak-menu-item .label { + flex: 1 1 0%; +} + +/* https://ariakit.org/examples/form-select */ +.bn-ak-button { + --border: rgb(0 0 0/13%); + --highlight: rgb(255 255 255/20%); + --shadow: rgb(0 0 0/10%); + display: flex; + height: 2.5rem; + user-select: none; + align-items: center; + gap: 0.25rem; + white-space: nowrap; + border-style: none; + background-color: hsl(204 20% 100%); + padding-left: 1rem; + padding-right: 1rem; + font-size: 1rem; + line-height: 1.5rem; + color: hsl(204 4% 0%); + text-decoration-line: none; + outline-width: 2px; + outline-offset: 2px; + outline-color: hsl(204 100% 40%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--highlight), + inset 0 -1px 0 var(--shadow), + 0 1px 1px var(--shadow); + justify-content: space-between; + width: 100%; + border-radius: 0.375rem; +} + +.bn-ak-button:where(.dark, .dark *) { + --border: rgb(255 255 255/10%); + --highlight: rgb(255 255 255/5%); + --shadow: rgb(0 0 0/25%); + background-color: hsl(204 20% 100% / 0.05); + color: hsl(204 20% 100%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 -1px 0 1px var(--shadow), + inset 0 1px 0 var(--highlight); +} + +.bn-ak-button:not(:active):hover { + --border: rgb(0 0 0/33%); +} + +.bn-ak-button:where(.dark, .dark *):not(:active):hover { + --border: rgb(255 255 255/25%); +} + +.bn-ak-primary { + --border: rgba(0, 0, 0, 0.15); + --highlight: rgba(255, 255, 255, 0.25); + --shadow: rgba(0, 0, 0, 0.15); + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); + justify-content: center; +} + +.bn-ak-primary:hover { + --border: rgba(0, 0, 0, 0.35); + background-color: hsl(204 100% 35%); +} + +.bn-ak-primary:where(.dark, .dark *) { + --border: rgba(255, 255, 255, 0.25); + --highlight: rgba(255, 255, 255, 0.1); + --shadow: rgba(0, 0, 0, 0.25); + background-color: hsl(204 100% 35%); +} + +.bn-ak-primary:hover:where(.dark, .dark *) { + --border: rgba(255, 255, 255, 0.45); + background-color: hsl(204 100% 40%); +} + +.bn-ak-button[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-button[data-focus-visible] { + outline-style: solid; +} + +.bn-ak-button:active, +.bn-ak-button[data-active] { + padding-top: 0.125rem; + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--border); +} + +@media (min-width: 640px) { + .bn-ak-button { + gap: 0.5rem; + } +} + +.bn-ak-button:active:where(.dark, .dark *), +.bn-ak-button[data-active]:where(.dark, .dark *) { + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 1px 1px 1px var(--shadow); +} + +.bn-ak-wrapper { + display: flex; + width: 320px; + max-width: 100%; + flex-direction: column; + gap: 1.5rem; + border-radius: 0.5rem; + background-color: hsl(204 20% 100%); + padding: 1rem; + box-shadow: + 0 1px 3px 0 rgb(0 0 0 / 0.1), + 0 1px 2px -1px rgb(0 0 0 / 0.1); +} + +.bn-ak-label { + padding-left: 1rem; +} + +.bn-ak-popover { + z-index: 50; + display: flex; + max-height: min(var(--popover-available-height, 300px), 300px); + flex-direction: column; + overflow: auto; + overscroll-behavior: contain; + border-radius: 0.5rem; + border-width: 1px; + border-style: solid; + border-color: hsl(204 20% 88%); + background-color: hsl(204 20% 100%); + padding: 0.5rem; + color: hsl(204 4% 0%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +.bn-ak-popover:where(.dark, .dark *) { + border-color: hsl(204 4% 24%); + background-color: hsl(204 4% 16%); + color: hsl(204 20% 100%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.25), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +.bn-ak-select-item { + display: flex; + cursor: default; + scroll-margin: 0.5rem; + align-items: center; + gap: 0.5rem; + border-radius: 0.25rem; + padding: 0.5rem; + outline: none !important; +} + +.bn-ak-select-item[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-select-item[data-active-item] { + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); +} + +.bn-ak-wrapper:where(.dark, .dark *) { + background-color: hsl(204 4% 16%); + box-shadow: + 0 1px 3px 0 rgb(0 0 0 / 0.25), + 0 1px 2px -1px rgb(0 0 0 / 0.1); +} + +.bn-ak-field { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.bn-ak-input { + height: 2.5rem; + width: 100%; + border-radius: 0.375rem; + border-style: none; + background-color: hsl(204 20% 94% / 0.4); + padding-left: 1rem; + padding-right: 1rem; + font-size: 1rem; + line-height: 1.5rem; + color: hsl(204 4% 0%); + box-shadow: + inset 0 0 0 1px rgba(0 0 0 / 0.1), + inset 0 2px 5px 0 rgba(0 0 0 / 0.05); +} + +.bn-ak-input::placeholder { + color: hsl(204 4% 0% / 0.6); +} + +.bn-ak-input:hover { + background-color: hsl(204 20% 94%); +} + +.bn-ak-popover:focus-visible, +.bn-ak-popover[data-focus-visible], +.bn-ak-input:focus-visible, +.bn-ak-input[data-focus-visible] { + outline: 2px solid hsl(204 100% 40%); + outline-offset: -1px; +} + +.bn-ak-input:where(.dark, .dark *) { + background-color: hsl(204 4% 10%); + color: hsl(204 20% 100%); + box-shadow: + inset 0 0 0 1px rgba(255 255 255 / 0.12), + inset 0 -1px 0 0 rgba(255 255 255 / 0.05), + inset 0 2px 5px 0 rgba(0 0 0 / 0.15); +} + +.bn-ak-input:where(.dark, .dark *)::placeholder { + color: hsl(204 20% 100% / 46%); +} + +.bn-ak-input:hover:where(.dark, .dark *) { + background-color: hsl(204 4% 8%); +} + +.bn-ak-error { + width: fit-content; + border-radius: 0.375rem; + border-width: 1px; + border-color: hsl(357 56% 80%); + background-color: hsl(357 56% 80% / 0.4); + padding-top: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 1rem; + padding-right: 1rem; + color: hsl(357 100% 30%); +} + +.bn-ak-error:empty { + display: none; +} + +.bn-ak-error:where(.dark, .dark *) { + border-color: hsl(357 56% 50% / 0.4); + background-color: hsl(357 56% 42% / 0.25); + color: hsl(357 100% 90%); +} + +.bn-ak-buttons { + display: flex; + gap: 1rem; + padding-top: 1rem; +} + +/* https://ariakit.org/components/menu */ +.bn-ak-button { + --border: rgb(0 0 0/13%); + --highlight: rgb(255 255 255/20%); + --shadow: rgb(0 0 0/10%); + display: flex; + height: 2.5rem; + user-select: none; + align-items: center; + justify-content: center; + gap: 0.25rem; + white-space: nowrap; + border-radius: 0.5rem; + border-style: none; + background-color: hsl(204 20% 100%); + padding-left: 1rem; + padding-right: 1rem; + font-size: 1rem; + line-height: 1.5rem; + color: hsl(204 4% 0%); + text-decoration-line: none; + outline-width: 2px; + outline-offset: 2px; + outline-color: hsl(204 100% 40%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--highlight), + inset 0 -1px 0 var(--shadow), + 0 1px 1px var(--shadow); + font-weight: 500; +} + +.bn-ak-button:where(.dark, .dark *) { + --border: rgb(255 255 255/10%); + --highlight: rgb(255 255 255/5%); + --shadow: rgb(0 0 0/25%); + background-color: hsl(204 20% 100% / 0.05); + color: hsl(204 20% 100%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 -1px 0 1px var(--shadow), + inset 0 1px 0 var(--highlight); +} + +.bn-ak-button:not(:active):hover { + --border: rgb(0 0 0/33%); +} + +.bn-ak-button:where(.dark, .dark *):not(:active):hover { + --border: rgb(255 255 255/25%); +} + +.bn-ak-button[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-button[data-focus-visible] { + outline-style: solid; +} + +.bn-ak-button:active, +.bn-ak-button[data-active] { + padding-top: 0.125rem; + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--border); +} + +@media (min-width: 640px) { + .bn-ak-button { + gap: 0.5rem; + } +} + +.bn-ak-button:active:where(.dark, .dark *), +.bn-ak-button[data-active]:where(.dark, .dark *) { + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 1px 1px 1px var(--shadow); +} + +.bn-ak-separator { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + height: 0px; + width: 100%; + border-top-width: 1px; + border-color: hsl(204 20% 88%); +} + +.bn-ak-separator:where(.dark, .dark *) { + border-color: hsl(204 4% 28%); +} + +.bn-ak-menu { + position: relative; + z-index: 50; + display: flex; + /*max-height: var(--popover-available-height);*/ + min-width: 180px; + flex-direction: column; + /*overflow: auto;*/ + overscroll-behavior: contain; + border-radius: 0.5rem; + border-width: 1px; + border-style: solid; + border-color: hsl(204 20% 88%); + background-color: hsl(204 20% 100%); + padding: 0.5rem; + color: hsl(204 4% 0%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); + outline: none !important; +} + +.bn-ak-menu:where(.dark, .dark *) { + border-color: hsl(204 4% 24%); + background-color: hsl(204 4% 16%); + color: hsl(204 20% 100%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.25), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +.bn-ak-menu-item { + display: flex; + cursor: default; + scroll-margin: 0.5rem; + align-items: center; + gap: 0.5rem; + border-radius: 0.25rem; + padding: 0.5rem; + outline: none !important; +} + +.bn-ak-menu-item[aria-disabled="true"] { + opacity: 0.25; +} + +.bn-ak-menu-item[data-active-item] { + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); +} + +.bn-ak-menu-item:active, +.bn-ak-menu-item[data-active] { + background-color: hsl(204 100% 32%); + padding-top: 9px; + padding-bottom: 7px; +} + +/* https://ariakit.org/examples/select-group */ +.bn-ak-button { + --border: rgb(0 0 0/13%); + --highlight: rgb(255 255 255/20%); + --shadow: rgb(0 0 0/10%); + display: flex; + height: 2.5rem; + user-select: none; + align-items: center; + gap: 0.25rem; + white-space: nowrap; + border-radius: 0.5rem; + border-style: none; + background-color: hsl(204 20% 100%); + padding-left: 1rem; + padding-right: 1rem; + font-size: 1rem; + line-height: 1.5rem; + color: hsl(204 4% 0%); + text-decoration-line: none; + outline-width: 2px; + outline-offset: 2px; + outline-color: hsl(204 100% 40%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--highlight), + inset 0 -1px 0 var(--shadow), + 0 1px 1px var(--shadow); + width: 200px; + justify-content: space-between; +} + +.bn-ak-button:where(.dark, .dark *) { + --border: rgb(255 255 255/10%); + --highlight: rgb(255 255 255/5%); + --shadow: rgb(0 0 0/25%); + background-color: hsl(204 20% 100% / 0.05); + color: hsl(204 20% 100%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 -1px 0 1px var(--shadow), + inset 0 1px 0 var(--highlight); +} + +.bn-ak-button:not(:active):hover { + --border: rgb(0 0 0/33%); +} + +.bn-ak-button:where(.dark, .dark *):not(:active):hover { + --border: rgb(255 255 255/25%); +} + +.bn-ak-button[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-button[data-focus-visible] { + outline-style: solid; +} + +.bn-ak-button:active, +.bn-ak-button[data-active] { + padding-top: 0.125rem; + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--border); +} + +@media (min-width: 640px) { + .bn-ak-button { + gap: 0.5rem; + } +} + +.bn-ak-button:active:where(.dark, .dark *), +.bn-ak-button[data-active]:where(.dark, .dark *) { + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 1px 1px 1px var(--shadow); +} + +.bn-ak-wrapper { + display: flex; + flex-direction: column; + gap: 0.5rem; + padding: 1rem; +} + +.bn-ak-popover { + z-index: 50; + display: flex; + max-height: min(var(--popover-available-height, 300px), 300px); + flex-direction: column; + overflow: auto; + overscroll-behavior: contain; + border-radius: 0.5rem; + border-width: 1px; + border-style: solid; + border-color: hsl(204 20% 88%); + background-color: hsl(204 20% 100%); + padding: 0.5rem; + color: hsl(204 4% 0%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +.bn-ak-popover:focus-visible, +.bn-ak-popover[data-focus-visible] { + outline: 2px solid hsl(204 100% 40%); + outline-offset: -1px; +} + +.bn-ak-popover:where(.dark, .dark *) { + border-color: hsl(204 4% 24%); + background-color: hsl(204 4% 16%); + color: hsl(204 20% 100%); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.25), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +.bn-ak-select-item { + display: flex; + cursor: default; + scroll-margin: 0.5rem; + align-items: center; + gap: 0.5rem; + border-radius: 0.25rem; + padding: 0.5rem; + outline: none !important; +} + +.bn-ak-select-item[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-select-item[data-active-item] { + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); +} + +.bn-ak-separator { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + height: 0px; + width: 100%; + border-top-width: 1px; + border-color: hsl(204 20% 88%); +} + +.bn-ak-separator:where(.dark, .dark *) { + border-color: hsl(204 4% 28%); +} + +.bn-ak-group-label { + cursor: default; + padding: 0.5rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; + opacity: 0.6; +} + +.bn-ak-group-label + * { + scroll-margin-top: 2.5rem; +} + +/* https://ariakit.org/components/tab */ +.bn-ak-wrapper { + display: flex; + flex-direction: column; + gap: 0.5rem; + border-radius: 0.5rem; + background-color: hsl(204 20% 100%); + padding: 0.5rem; + box-shadow: + 0 1px 3px 0 rgb(0 0 0 / 0.1), + 0 1px 2px -1px rgb(0 0 0 / 0.1); +} + +.bn-ak-wrapper:where(.dark, .dark *) { + background-color: hsl(204 4% 16%); + box-shadow: + 0 1px 3px 0 rgb(0 0 0 / 0.25), + 0 1px 2px -1px rgb(0 0 0 / 0.1); +} + +.bn-ak-tab-list { + display: flex; + gap: 0.5rem; +} + +.bn-ak-tab { + display: flex; + height: 2.5rem; + user-select: none; + align-items: center; + justify-content: center; + gap: 0.5rem; + white-space: nowrap; + border-radius: 0.25rem; + border-style: none; + padding-left: 1rem; + padding-right: 1rem; + font-size: 1rem; + line-height: 1.5rem; + text-decoration-line: none; + outline-width: 2px; + outline-offset: 2px; + outline-color: hsl(204 100% 40%); +} + +.bn-ak-tab:hover { + background-color: hsl(204 4% 0% / 7.5%); +} + +.bn-ak-tab[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-tab[aria-selected="true"] { + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); +} + +.bn-ak-tab:hover[aria-selected="true"] { + background-color: hsl(204 100% 32%); +} + +.bn-ak-tab[data-focus-visible] { + outline-style: solid; +} + +.bn-ak-tab:active, +.bn-ak-tab[data-active] { + padding-top: 0.125rem; +} + +.bn-ak-tab:hover:where(.dark, .dark *) { + background-color: hsl(204 20% 100% / 0.1); +} + +.bn-ak-tab[aria-selected="true"]:where(.dark, .dark *) { + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); +} + +.bn-ak-tab:hover[aria-selected="true"]:where(.dark, .dark *) { + background-color: hsl(204 100% 32%); +} + +.bn-ak-panels { + padding: 0.5rem; +} + +/* https://ariakit.org/components/toolbar */ +.bn-ak-button { + --border: rgb(0 0 0/13%); + --highlight: rgb(255 255 255/20%); + --shadow: rgb(0 0 0/10%); + display: flex; + height: 2.5rem; + user-select: none; + align-items: center; + justify-content: center; + white-space: nowrap; + border-style: none; + background-color: hsl(204 20% 100%); + padding-left: 1rem; + padding-right: 1rem; + font-size: 1rem; + line-height: 1.5rem; + color: hsl(204 4% 0%); + text-decoration-line: none; + outline-width: 2px; + outline-offset: 2px; + outline-color: hsl(204 100% 40%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--highlight), + inset 0 -1px 0 var(--shadow), + 0 1px 1px var(--shadow); + scroll-margin-left: 0.25rem; + scroll-margin-right: 0.25rem; + gap: 0.5rem; + border-radius: 0.25rem; +} + +.bn-ak-button:where(.dark, .dark *) { + --border: rgb(255 255 255/10%); + --highlight: rgb(255 255 255/5%); + --shadow: rgb(0 0 0/25%); + background-color: hsl(204 20% 100% / 0.05); + color: hsl(204 20% 100%); + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 -1px 0 1px var(--shadow), + inset 0 1px 0 var(--highlight); +} + +.bn-ak-button:not(:active):hover { + --border: rgb(0 0 0/33%); +} + +.bn-ak-button:where(.dark, .dark *):not(:active):hover { + --border: rgb(255 255 255/25%); +} + +.bn-ak-button[aria-disabled="true"] { + opacity: 0.5; +} + +.bn-ak-button[data-focus-visible] { + outline-style: solid; +} + +.bn-ak-button:active, +.bn-ak-button[data-active] { + padding-top: 0.125rem; + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--border); +} + +@media (min-width: 640px) { + .bn-ak-button { + gap: 0.5rem; + } +} + +.bn-ak-button:active:where(.dark, .dark *), +.bn-ak-button[data-active]:where(.dark, .dark *) { + box-shadow: + inset 0 0 0 1px var(--border), + inset 0 1px 1px 1px var(--shadow); +} + +.bn-ak-secondary { + background-color: transparent; + color: currentColor; + box-shadow: none; +} + +.bn-ak-secondary:hover { + background-color: hsl(204 4% 0% / 0.05); +} + +.bn-ak-secondary:where(.dark, .dark *) { + background-color: transparent; + box-shadow: none; +} + +.bn-ak-secondary:hover:where(.dark, .dark *) { + background-color: hsl(204 20% 100% / 0.05); +} + +.bn-ak-secondary:active:where(.dark, .dark *), +.bn-ak-secondary[data-active]:where(.dark, .dark *) { + box-shadow: none; +} + +.bn-ak-toolbar { + display: flex; + max-width: 100%; + align-items: center; + gap: 0.25rem; + overflow-x: auto; + border-radius: 0.5rem; + background-color: hsl(204 20% 100%); + padding: 0.25rem; + box-shadow: + 0 1px 3px 0 rgb(0 0 0 / 0.1), + 0 1px 2px -1px rgb(0 0 0 / 0.1); +} + +.bn-ak-toolbar:where(.dark, .dark *) { + background-color: hsl(204 4% 16%); + box-shadow: + 0 1px 3px 0 rgb(0 0 0 / 0.25), + 0 1px 2px -1px rgb(0 0 0 / 0.1); +} + +.bn-ak-separator { + height: 2rem; + border-right-width: 1px; + border-color: hsl(204 20% 88%); +} + +.bn-ak-separator:where(.dark, .dark *) { + border-color: hsl(204 4% 28%); +} \ No newline at end of file diff --git a/packages/ariakit/src/index.tsx b/packages/ariakit/src/index.tsx new file mode 100644 index 0000000000..81da5122d5 --- /dev/null +++ b/packages/ariakit/src/index.tsx @@ -0,0 +1,99 @@ +import { + BlockNoteViewRaw, + Components, + ComponentsContext, +} from "@blocknote/react"; +import { ComponentProps } from "react"; + +import { Form } from "./input/Form"; +import { TextInput } from "./input/TextInput"; +import { + Menu, + MenuDivider, + MenuDropdown, + MenuItem, + MenuLabel, + MenuTrigger, +} from "./menu/Menu"; +import { Panel } from "./panel/Panel"; +import { PanelButton } from "./panel/PanelButton"; +import { PanelFileInput } from "./panel/PanelFileInput"; +import { PanelTab } from "./panel/PanelTab"; +import { PanelTextInput } from "./panel/PanelTextInput"; +import { Popover, PopoverContent, PopoverTrigger } from "./popover/Popover"; +import { SideMenu } from "./sideMenu/SideMenu"; +import { SideMenuButton } from "./sideMenu/SideMenuButton"; +import { SuggestionMenu } from "./suggestionMenu/SuggestionMenu"; +import { SuggestionMenuItem } from "./suggestionMenu/SuggestionMenuItem"; +import { SuggestionMenuEmptyItem } from "./suggestionMenu/SuggestionMenuEmptyItem"; +import { SuggestionMenuLabel } from "./suggestionMenu/SuggestionMenuLabel"; +import { SuggestionMenuLoader } from "./suggestionMenu/SuggestionMenuLoader"; +import { TableHandle } from "./tableHandle/TableHandle"; +import { Toolbar } from "./toolbar/Toolbar"; +import { ToolbarButton } from "./toolbar/ToolbarButton"; +import { ToolbarSelect } from "./toolbar/ToolbarSelect"; + +import "./style.css"; + +export const components: Components = { + FormattingToolbar: { + Root: Toolbar, + Button: ToolbarButton, + Select: ToolbarSelect, + }, + ImagePanel: { + Root: Panel, + Button: PanelButton, + FileInput: PanelFileInput, + TabPanel: PanelTab, + TextInput: PanelTextInput, + }, + LinkToolbar: { + Root: Toolbar, + Button: ToolbarButton, + }, + SideMenu: { + Root: SideMenu, + Button: SideMenuButton, + }, + SuggestionMenu: { + Root: SuggestionMenu, + Item: SuggestionMenuItem, + EmptyItem: SuggestionMenuEmptyItem, + Label: SuggestionMenuLabel, + Loader: SuggestionMenuLoader, + }, + TableHandle: { + Root: TableHandle, + }, + Generic: { + Form: { + Root: Form, + TextInput: TextInput, + }, + Menu: { + Root: Menu, + Trigger: MenuTrigger, + Dropdown: MenuDropdown, + Divider: MenuDivider, + Label: MenuLabel, + Item: MenuItem, + }, + Popover: { + Root: Popover, + Trigger: PopoverTrigger, + Content: PopoverContent, + }, + }, +}; + +export const BlockNoteView = ( + // TODO: Fix typing + props: ComponentProps> +) => { + return ( + + + + ); +}; diff --git a/packages/ariakit/src/input/Form.tsx b/packages/ariakit/src/input/Form.tsx new file mode 100644 index 0000000000..e12de4f09f --- /dev/null +++ b/packages/ariakit/src/input/Form.tsx @@ -0,0 +1,9 @@ +import * as Ariakit from "@ariakit/react"; + +import { ComponentProps } from "@blocknote/react"; + +export const Form = (props: ComponentProps["Generic"]["Form"]["Root"]) => { + const { children } = props; + + return {children}; +}; diff --git a/packages/ariakit/src/input/TextInput.tsx b/packages/ariakit/src/input/TextInput.tsx new file mode 100644 index 0000000000..4bcb781049 --- /dev/null +++ b/packages/ariakit/src/input/TextInput.tsx @@ -0,0 +1,45 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const TextInput = forwardRef< + HTMLInputElement, + ComponentProps["Generic"]["Form"]["TextInput"] +>((props, ref) => { + const { + className, + name, + label, + icon, + value, + autoFocus, + placeholder, + onKeyDown, + onChange, + onSubmit, + } = props; + + return ( + <> + {props.label && ( + {label} + )} +
+ {icon} + +
+ + ); +}); diff --git a/packages/ariakit/src/menu/Menu.tsx b/packages/ariakit/src/menu/Menu.tsx new file mode 100644 index 0000000000..cf2f9dcb83 --- /dev/null +++ b/packages/ariakit/src/menu/Menu.tsx @@ -0,0 +1,111 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const Menu = (props: ComponentProps["Generic"]["Menu"]["Root"]) => { + const { + children, + onOpenChange, + position, + // sub + } = props; + + return ( + + {children} + + ); +}; + +export const MenuDropdown = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Dropdown"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); + +export const MenuItem = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Item"] +>((props, ref) => { + const { className, children, icon, checked, subTrigger, onClick } = props; + + if (subTrigger) { + return ( + } + className={mergeCSSClasses("bn-ak-menu-item", className || "")} + ref={ref} + onClick={onClick}> + {icon} + {children} + + {checked !== undefined && } + + ); + } + return ( + + {icon} + {children} + {checked !== undefined && } + + ); +}); + +export const MenuLabel = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Label"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); + +export const MenuTrigger = ( + props: ComponentProps["Generic"]["Menu"]["Trigger"] +) => { + const { children, sub } = props; + + if (sub) { + return children; + } + + return ; +}; + +export const MenuDivider = forwardRef< + HTMLHRElement, + ComponentProps["Generic"]["Menu"]["Divider"] +>((props, ref) => { + const { className } = props; + + return ( + + ); +}); diff --git a/packages/ariakit/src/panel/Panel.tsx b/packages/ariakit/src/panel/Panel.tsx new file mode 100644 index 0000000000..553c7b6678 --- /dev/null +++ b/packages/ariakit/src/panel/Panel.tsx @@ -0,0 +1,53 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const Panel = forwardRef< + HTMLDivElement, + ComponentProps["ImagePanel"]["Root"] +>((props, ref) => { + const { + className, + tabs, + defaultOpenTab, + openTab, + setOpenTab, + // loading, + // setLoading, + } = props; + + return ( +
+ { + if (activeId) { + setOpenTab(activeId); + } + }}> + {/*{loading && }*/} + + + {tabs.map((tab) => ( + + {tab.name} + + ))} + + +
+ {tabs.map((tab) => ( + + {tab.tabPanel} + + ))} +
+
+
+ ); +}); diff --git a/packages/ariakit/src/panel/PanelButton.tsx b/packages/ariakit/src/panel/PanelButton.tsx new file mode 100644 index 0000000000..04c300c18d --- /dev/null +++ b/packages/ariakit/src/panel/PanelButton.tsx @@ -0,0 +1,21 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelButton = forwardRef< + HTMLButtonElement, + ComponentProps["ImagePanel"]["Button"] +>((props, ref) => { + const { className, children, onClick } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/ariakit/src/panel/PanelFileInput.tsx b/packages/ariakit/src/panel/PanelFileInput.tsx new file mode 100644 index 0000000000..36df131840 --- /dev/null +++ b/packages/ariakit/src/panel/PanelFileInput.tsx @@ -0,0 +1,25 @@ +import * as Ariakit from "@ariakit/react"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelFileInput = forwardRef< + HTMLInputElement, + ComponentProps["ImagePanel"]["FileInput"] +>((props, ref) => { + const { className, value, placeholder, onChange } = props; + + return ( + + onChange?.(e.target.files![0])} + placeholder={placeholder} + /> + + ); +}); diff --git a/packages/ariakit/src/panel/PanelTab.tsx b/packages/ariakit/src/panel/PanelTab.tsx new file mode 100644 index 0000000000..58ed2aba46 --- /dev/null +++ b/packages/ariakit/src/panel/PanelTab.tsx @@ -0,0 +1,15 @@ +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelTab = forwardRef< + HTMLDivElement, + ComponentProps["ImagePanel"]["TabPanel"] +>((props, ref) => { + const { className, children } = props; + + return ( +
+ {children} +
+ ); +}); diff --git a/packages/ariakit/src/panel/PanelTextInput.tsx b/packages/ariakit/src/panel/PanelTextInput.tsx new file mode 100644 index 0000000000..3e7f9c2ac4 --- /dev/null +++ b/packages/ariakit/src/panel/PanelTextInput.tsx @@ -0,0 +1,27 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelTextInput = forwardRef< + HTMLInputElement, + ComponentProps["ImagePanel"]["TextInput"] +>((props, ref) => { + const { className, value, placeholder, onKeyDown, onChange } = props; + + return ( + + + + ); +}); diff --git a/packages/ariakit/src/popover/Popover.tsx b/packages/ariakit/src/popover/Popover.tsx new file mode 100644 index 0000000000..71adb6f07f --- /dev/null +++ b/packages/ariakit/src/popover/Popover.tsx @@ -0,0 +1,41 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PopoverTrigger = forwardRef< + HTMLButtonElement, + ComponentProps["Generic"]["Popover"]["Trigger"] +>((props, ref) => { + const { children } = props; + + return ; +}); + +export const PopoverContent = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Popover"]["Content"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); + +export const Popover = ( + props: ComponentProps["Generic"]["Popover"]["Root"] +) => { + const { children, opened, position } = props; + + return ( + + {children} + + ); +}; diff --git a/packages/ariakit/src/sideMenu/SideMenu.tsx b/packages/ariakit/src/sideMenu/SideMenu.tsx new file mode 100644 index 0000000000..742112d71c --- /dev/null +++ b/packages/ariakit/src/sideMenu/SideMenu.tsx @@ -0,0 +1,17 @@ +import * as Ariakit from "@ariakit/react"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SideMenu = forwardRef< + HTMLDivElement, + ComponentProps["SideMenu"]["Root"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/ariakit/src/sideMenu/SideMenuButton.tsx b/packages/ariakit/src/sideMenu/SideMenuButton.tsx new file mode 100644 index 0000000000..60ed1b7675 --- /dev/null +++ b/packages/ariakit/src/sideMenu/SideMenuButton.tsx @@ -0,0 +1,25 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SideMenuButton = forwardRef< + HTMLButtonElement, + ComponentProps["SideMenu"]["Button"] +>((props, ref) => { + const { className, children, icon, onClick } = props; + + return ( + + {icon} + {children} + + ); +}); diff --git a/packages/ariakit/src/style.css b/packages/ariakit/src/style.css new file mode 100644 index 0000000000..974dffbb29 --- /dev/null +++ b/packages/ariakit/src/style.css @@ -0,0 +1,125 @@ +@import url("@blocknote/react/style.css"); + +/* This file contains BlockNote-specific fixes for the styles in + ariakitStyles.css. */ + +@import "./ariakitStyles.css"; + +.bn-ak-input-wrapper { + align-items: center; + display: flex; + gap: 0.5rem; +} + +.bn-toolbar .bn-ak-button { + width: unset; +} + +.bn-toolbar .bn-ak-button[data-selected] { + padding-top: 0.125rem; + box-shadow: inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--border); +} + +.bn-toolbar .bn-ak-button[data-selected]:where(.dark, .dark *) { + box-shadow: inset 0 0 0 1px var(--border), + inset 0 1px 1px 1px var(--shadow); +} + +.bn-toolbar .bn-ak-popover { + gap: 0.5rem; +} + +.bn-tab-panel { + align-items: center; + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.bn-file-input { + max-width: 100%; +} + +.bn-ak-menu-item[data-hovered] { + background-color: hsl(204 100% 40%); + color: hsl(204 20% 100%); +} + +.bn-ak-menu-item { + display: flex; +} + +.bn-dropdown { + overflow: visible; +} + +.bn-suggestion-menu, .bn-color-picker-dropdown { + overflow: scroll; +} + +.bn-ak-suggestion-menu-item-body { + flex: 1; +} + +.bn-ak-suggestion-menu-item-subtitle { + font-size: 0.7rem; +} + +.bn-ak-suggestion-menu-item-section[data-position="left"] { + padding: 8px; +} + +.bn-ak-suggestion-menu-item-section[data-position="right"] { + --border: rgb(0 0 0/13%); + --highlight: rgb(255 255 255/20%); + --shadow: rgb(0 0 0/10%); + box-shadow: inset 0 0 0 1px var(--border), + inset 0 2px 0 var(--highlight), + inset 0 -1px 0 var(--shadow), + 0 1px 1px var(--shadow); + font-size: 0.7rem; + border-radius: 4px; + padding-inline: 4px; +} + +.bn-side-menu { + align-items: center; + display: flex; + justify-content: center; +} + +.bn-side-menu .bn-ak-button { + height: fit-content; + padding: 0; + width: fit-content; +} + +.bn-panel-popover { + background-color: transparent; + border: none; + box-shadow: none; +} + +.bn-table-handle { + height: fit-content; + padding: 0; + width: fit-content; +} + +.bn-side-menu, .bn-table-handle { + color: gray; +} + +.bn-ak-button:where(.dark, .dark *) { + color: hsl(204 20% 100%); +} + +.bn-ak-tab, .bn-file-input { + background-color: transparent; + color: black; +} + +.bn-ak-tab:where(.dark, .dark *), .bn-file-input:where(.dark, .dark *) { + color: white; +} \ No newline at end of file diff --git a/packages/ariakit/src/suggestionMenu/SuggestionMenu.tsx b/packages/ariakit/src/suggestionMenu/SuggestionMenu.tsx new file mode 100644 index 0000000000..4229250989 --- /dev/null +++ b/packages/ariakit/src/suggestionMenu/SuggestionMenu.tsx @@ -0,0 +1,20 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenu = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Root"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/ariakit/src/suggestionMenu/SuggestionMenuEmptyItem.tsx b/packages/ariakit/src/suggestionMenu/SuggestionMenuEmptyItem.tsx new file mode 100644 index 0000000000..9729f0685b --- /dev/null +++ b/packages/ariakit/src/suggestionMenu/SuggestionMenuEmptyItem.tsx @@ -0,0 +1,18 @@ +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenuEmptyItem = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["EmptyItem"] +>((props, ref) => { + const { className, children } = props; + + return ( +
+
{children}
+
+ ); +}); diff --git a/packages/ariakit/src/suggestionMenu/SuggestionMenuItem.tsx b/packages/ariakit/src/suggestionMenu/SuggestionMenuItem.tsx new file mode 100644 index 0000000000..a6cdee6b26 --- /dev/null +++ b/packages/ariakit/src/suggestionMenu/SuggestionMenuItem.tsx @@ -0,0 +1,61 @@ +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef, useCallback } from "react"; + +export const SuggestionMenuItem = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Item"] +>((props, ref) => { + const { + className, + title, + subtext, + // group, + icon, + badge, + // aliases, + // onItemClick, + isSelected, + setSelected, + onClick, + } = props; + + const handleMouseLeave = useCallback(() => { + setSelected?.(false); + }, [setSelected]); + + const handleMouseEnter = useCallback(() => { + setSelected?.(true); + }, [setSelected]); + + return ( +
+ {icon && ( +
+ {icon} +
+ )} +
+
{title}
+
{subtext}
+
+ {badge && ( +
+
{badge}
+
+ )} +
+ ); +}); diff --git a/packages/ariakit/src/suggestionMenu/SuggestionMenuLabel.tsx b/packages/ariakit/src/suggestionMenu/SuggestionMenuLabel.tsx new file mode 100644 index 0000000000..63e77d2cab --- /dev/null +++ b/packages/ariakit/src/suggestionMenu/SuggestionMenuLabel.tsx @@ -0,0 +1,18 @@ +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenuLabel = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Label"] +>((props, ref) => { + const { className, children } = props; + + return ( +
+ {children} +
+ ); +}); diff --git a/packages/ariakit/src/suggestionMenu/SuggestionMenuLoader.tsx b/packages/ariakit/src/suggestionMenu/SuggestionMenuLoader.tsx new file mode 100644 index 0000000000..0b64e5496f --- /dev/null +++ b/packages/ariakit/src/suggestionMenu/SuggestionMenuLoader.tsx @@ -0,0 +1,16 @@ +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenuLoader = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Loader"] +>((props, ref) => { + const { className, children } = props; + + // TODO Test + return ( +
+ {children} +
+ ); +}); diff --git a/packages/ariakit/src/tableHandle/TableHandle.tsx b/packages/ariakit/src/tableHandle/TableHandle.tsx new file mode 100644 index 0000000000..4c798d6637 --- /dev/null +++ b/packages/ariakit/src/tableHandle/TableHandle.tsx @@ -0,0 +1,36 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const TableHandle = forwardRef< + HTMLButtonElement, + ComponentProps["TableHandle"]["Root"] +>((props, ref) => { + const { + className, + children, + draggable, + onDragStart, + onDragEnd, + style, + ...rest + } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/ariakit/src/toolbar/Toolbar.tsx b/packages/ariakit/src/toolbar/Toolbar.tsx new file mode 100644 index 0000000000..c47874b0c9 --- /dev/null +++ b/packages/ariakit/src/toolbar/Toolbar.tsx @@ -0,0 +1,24 @@ +import * as Ariakit from "@ariakit/react"; + +import { mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +type ToolbarProps = ComponentProps["FormattingToolbar"]["Root"] & + ComponentProps["LinkToolbar"]["Root"]; + +export const Toolbar = forwardRef( + (props, ref) => { + const { className, children, onMouseEnter, onMouseLeave } = props; + + return ( + + {children} + + ); + } +); diff --git a/packages/ariakit/src/toolbar/ToolbarButton.tsx b/packages/ariakit/src/toolbar/ToolbarButton.tsx new file mode 100644 index 0000000000..12e03320ff --- /dev/null +++ b/packages/ariakit/src/toolbar/ToolbarButton.tsx @@ -0,0 +1,88 @@ +import * as Ariakit from "@ariakit/react"; + +import { isSafari, mergeCSSClasses } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +type ToolbarButtonProps = ComponentProps["FormattingToolbar"]["Button"] & + ComponentProps["LinkToolbar"]["Button"]; + +/** + * Helper for basic buttons that show in the formatting toolbar. + */ +// TODO: implement tooltip +export const ToolbarButton = forwardRef( + (props, ref) => { + const { + className, + children, + // mainTooltip, + // secondaryTooltip, + icon, + isSelected, + isDisabled, + onClick, + } = props; + + return ( + { + if (isSafari()) { + (e.currentTarget as HTMLButtonElement).focus(); + } + }} + onClick={onClick} + data-selected={isSelected ? "true" : undefined} + data-test={ + props.mainTooltip.slice(0, 1).toLowerCase() + + props.mainTooltip.replace(/\s+/g, "").slice(1) + } + // size={"xs"} + disabled={isDisabled || false} + ref={ref}> + {icon} + {children} + + ); + + // return ( + // + // { + // if (isSafari()) { + // (e.currentTarget as HTMLButtonElement).focus(); + // } + // }} + // onClick={props.onClick} + // data-selected={props.isSelected ? "true" : undefined} + // data-test={ + // props.mainTooltip.slice(0, 1).toLowerCase() + + // props.mainTooltip.replace(/\s+/g, "").slice(1) + // } + // // size={"xs"} + // disabled={props.isDisabled || false} + // ref={ref}> + // }> + // {props.icon} + // {props.children} + // + // + //
{props.mainTooltip}
+ // {props.secondaryTooltip &&
{props.secondaryTooltip}
} + //
+ //
+ // ); + } +); diff --git a/packages/ariakit/src/toolbar/ToolbarSelect.tsx b/packages/ariakit/src/toolbar/ToolbarSelect.tsx new file mode 100644 index 0000000000..930a281380 --- /dev/null +++ b/packages/ariakit/src/toolbar/ToolbarSelect.tsx @@ -0,0 +1,45 @@ +import * as Ariakit from "@ariakit/react"; + +import { ComponentProps } from "@blocknote/react"; +import { mergeCSSClasses } from "@blocknote/core"; +import { forwardRef } from "react"; + +export const ToolbarSelect = forwardRef< + HTMLDivElement, + ComponentProps["FormattingToolbar"]["Select"] +>((props, ref) => { + const { className, items, isDisabled } = props; + + const selectedItem = props.items.filter((p) => p.isSelected)[0]; + + const setValue = (value: string) => { + items.find((item) => item.text === value)!.onClick?.(); + }; + + return ( + + }> + {selectedItem.icon} {selectedItem.text} + + + {items.map((option) => ( + + {option.icon} + {option.text} + {option.text === selectedItem.text && } + + ))} + + + ); +}); diff --git a/packages/ariakit/tsconfig.json b/packages/ariakit/tsconfig.json new file mode 100644 index 0000000000..607ad93cfa --- /dev/null +++ b/packages/ariakit/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "Node", + "jsx": "react-jsx", + "strict": true, + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "noEmit": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "outDir": "dist", + "declaration": true, + "declarationDir": "types", + "composite": true, + "skipLibCheck": true, + }, + "include": ["src"], + "references": [ + { + "path": "../core" + }, + { + "path": "../react" + } + ] +} diff --git a/packages/ariakit/vite.config.ts b/packages/ariakit/vite.config.ts new file mode 100644 index 0000000000..a50e2823d2 --- /dev/null +++ b/packages/ariakit/vite.config.ts @@ -0,0 +1,52 @@ +import react from "@vitejs/plugin-react"; +import * as path from "path"; +import { webpackStats } from "rollup-plugin-webpack-stats"; +import { defineConfig } from "vite"; +import pkg from "./package.json"; +// import eslintPlugin from "vite-plugin-eslint"; + +// https://vitejs.dev/config/ +export default defineConfig((conf) => ({ + test: { + environment: "jsdom", + setupFiles: ["./vitestSetup.ts"], + }, + plugins: [react(), webpackStats()], + // used so that vitest resolves the core package from the sources instead of the built version + resolve: { + alias: + conf.command === "build" + ? ({} as Record) + : ({ + // load live from sources with live reload working + "@blocknote/core": path.resolve(__dirname, "../core/src/"), + "@blocknote/react": path.resolve(__dirname, "../react/src/"), + } as Record), + }, + build: { + sourcemap: true, + lib: { + entry: path.resolve(__dirname, "src/index.tsx"), + name: "blocknote-ariakit", + fileName: "blocknote-ariakit", + }, + rollupOptions: { + // make sure to externalize deps that shouldn't be bundled + // into your library + external: Object.keys({ + ...pkg.dependencies, + ...pkg.peerDependencies, + ...pkg.devDependencies, + }), + output: { + // Provide global variables to use in the UMD build + // for externalized deps + globals: { + react: "React", + "react-dom": "ReactDOM", + }, + interop: "compat", // https://rollupjs.org/migration/#changed-defaults + }, + }, + }, +})); diff --git a/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts b/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts index 21f8eeeb00..af1e444a99 100644 --- a/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts +++ b/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts @@ -76,7 +76,7 @@ export const renderImage = ( // Text for the add image button. const addImageButtonText = document.createElement("p"); addImageButtonText.className = "bn-add-image-button-text"; - addImageButtonText.innerText = "Add Image"; + addImageButtonText.innerText = editor.dictionary.image.add_button; // Wrapper element for the image, resize handles and caption. const imageAndCaptionWrapper = document.createElement("div"); diff --git a/packages/core/src/editor/BlockNoteEditor.ts b/packages/core/src/editor/BlockNoteEditor.ts index 001782123b..9a12f039b4 100644 --- a/packages/core/src/editor/BlockNoteEditor.ts +++ b/packages/core/src/editor/BlockNoteEditor.ts @@ -27,10 +27,10 @@ import { PartialBlock, } from "../blocks/defaultBlocks"; import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin"; +import { ImagePanelProsemirrorPlugin } from "../extensions/ImagePanel/ImageToolbarPlugin"; import { LinkToolbarProsemirrorPlugin } from "../extensions/LinkToolbar/LinkToolbarPlugin"; import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin"; import { SuggestionMenuProseMirrorPlugin } from "../extensions/SuggestionMenu/SuggestionPlugin"; -import { ImagePanelProsemirrorPlugin } from "../extensions/ImagePanel/ImageToolbarPlugin"; import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin"; import { UniqueID } from "../extensions/UniqueID/UniqueID"; import { @@ -62,6 +62,8 @@ import { } from "./BlockNoteTipTapEditor"; // CSS +import { PlaceholderPlugin } from "../extensions/Placeholder/PlaceholderPlugin"; +import { en } from "../i18n/locales"; import "./Block.css"; import "./editor.css"; @@ -150,6 +152,8 @@ export class BlockNoteEditor< contentComponent: any; }; public blockCache = new WeakMap>(); + public readonly dictionary = en; + public readonly schema: BlockNoteSchema; public readonly blockImplementations: BlockSpecs; @@ -221,6 +225,10 @@ export class BlockNoteEditor< defaultStyles: true, schema: options.schema || BlockNoteSchema.create(), ...options, + placeholders: { + ...this.dictionary.placeholders, + ...options.placeholders, + }, }; // @ts-ignore @@ -243,7 +251,6 @@ export class BlockNoteEditor< const extensions = getBlockNoteExtensions({ editor: this, - placeholders: newOptions.placeholders, domAttributes: newOptions.domAttributes || {}, blockSchema: this.schema.blockSchema, blockSpecs: this.schema.blockSpecs, @@ -263,6 +270,7 @@ export class BlockNoteEditor< this.suggestionMenus.plugin, ...(this.imagePanel ? [this.imagePanel.plugin] : []), ...(this.tableHandles ? [this.tableHandles.plugin] : []), + PlaceholderPlugin(this, newOptions.placeholders), ]; }, }); diff --git a/packages/core/src/editor/BlockNoteExtensions.ts b/packages/core/src/editor/BlockNoteExtensions.ts index 2cf41f98f8..a408c00f3e 100644 --- a/packages/core/src/editor/BlockNoteExtensions.ts +++ b/packages/core/src/editor/BlockNoteExtensions.ts @@ -14,7 +14,6 @@ import * as Y from "yjs"; import { createCopyToClipboardExtension } from "../api/exporters/copyExtension"; import { createPasteFromClipboardExtension } from "../api/parsers/pasteExtension"; import { BackgroundColorExtension } from "../extensions/BackgroundColor/BackgroundColorExtension"; -import { Placeholder } from "../extensions/Placeholder/PlaceholderExtension"; import { TextAlignmentExtension } from "../extensions/TextAlignment/TextAlignmentExtension"; import { TextColorExtension } from "../extensions/TextColor/TextColorExtension"; import { TrailingNode } from "../extensions/TrailingNode/TrailingNodeExtension"; @@ -39,7 +38,6 @@ export const getBlockNoteExtensions = < S extends StyleSchema >(opts: { editor: BlockNoteEditor; - placeholders?: Record; domAttributes: Partial; blockSchema: BSchema; blockSpecs: BlockSpecs; @@ -66,12 +64,6 @@ export const getBlockNoteExtensions = < Gapcursor, // DropCursor, - Placeholder.configure({ - // TODO: This shorthand is kind of ugly - ...(opts.placeholders !== undefined - ? { placeholders: opts.placeholders } - : {}), - }), UniqueID.configure({ types: ["blockContainer"], }), diff --git a/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts b/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts deleted file mode 100644 index b25e6d4c5a..0000000000 --- a/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Extension } from "@tiptap/core"; -import { Plugin, PluginKey } from "prosemirror-state"; -import { Decoration, DecorationSet } from "prosemirror-view"; - -const PLUGIN_KEY = new PluginKey(`blocknote-placeholder`); - -/** - * This is a modified version of the tiptap - * placeholder plugin, that also sets hasAnchorClass - * - * It does not set a data-placeholder (text is currently done in css) - * - */ -export interface PlaceholderOptions { - placeholders: Record; -} - -export const Placeholder = Extension.create({ - name: "placeholder", - - addOptions() { - return { - placeholders: { - default: "Enter text or type '/' for commands", - heading: "Heading", - bulletListItem: "List", - numberedListItem: "List", - }, - }; - }, - - addProseMirrorPlugins() { - const placeholders = this.options.placeholders; - return [ - new Plugin({ - key: PLUGIN_KEY, - view: () => { - const styleEl = document.createElement("style"); - document.head.appendChild(styleEl); - const styleSheet = styleEl.sheet!; - - const getBaseSelector = (additionalSelectors = "") => - `.bn-block-content${additionalSelectors} .bn-inline-content:has(> .ProseMirror-trailingBreak):before`; - - const getSelector = ( - blockType: string | "default", - mustBeFocused = true - ) => { - const mustBeFocusedSelector = mustBeFocused - ? `[data-is-empty-and-focused]` - : ``; - - if (blockType === "default") { - return getBaseSelector(mustBeFocusedSelector); - } - - const blockTypeSelector = `[data-content-type="${blockType}"]`; - return getBaseSelector(mustBeFocusedSelector + blockTypeSelector); - }; - - for (const [blockType, placeholder] of Object.entries(placeholders)) { - const mustBeFocused = blockType === "default"; - - styleSheet.insertRule( - `${getSelector( - blockType, - mustBeFocused - )}{ content: ${JSON.stringify(placeholder)}; }` - ); - - // For some reason, the placeholders which show when the block is focused - // take priority over ones which show depending on block type, so we need - // to make sure the block specific ones are also used when the block is - // focused. - if (!mustBeFocused) { - styleSheet.insertRule( - `${getSelector(blockType, true)}{ content: ${JSON.stringify( - placeholder - )}; }` - ); - } - } - - return { - destroy: () => { - document.head.removeChild(styleEl); - }, - }; - }, - props: { - // TODO: maybe also add placeholder for empty document ("e.g.: start writing..") - decorations: (state) => { - const { doc, selection } = state; - - const active = this.editor.isEditable; - - if (!active) { - return; - } - - if (!selection.empty) { - return; - } - - const $pos = selection.$anchor; - const node = $pos.parent; - - if (node.content.size > 0) { - return null; - } - - const before = $pos.before(); - - const dec = Decoration.node(before, before + node.nodeSize, { - "data-is-empty-and-focused": "true", - }); - - return DecorationSet.create(doc, [dec]); - }, - }, - }), - ]; - }, -}); diff --git a/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts new file mode 100644 index 0000000000..aa7f423126 --- /dev/null +++ b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts @@ -0,0 +1,95 @@ +import { Plugin, PluginKey } from "prosemirror-state"; +import { Decoration, DecorationSet } from "prosemirror-view"; +import type { BlockNoteEditor } from "../../editor/BlockNoteEditor"; + +const PLUGIN_KEY = new PluginKey(`blocknote-placeholder`); + +export const PlaceholderPlugin = ( + editor: BlockNoteEditor, + placeholders: Record +) => { + return new Plugin({ + key: PLUGIN_KEY, + view: () => { + const styleEl = document.createElement("style"); + document.head.appendChild(styleEl); + const styleSheet = styleEl.sheet!; + + const getBaseSelector = (additionalSelectors = "") => + `.bn-block-content${additionalSelectors} .bn-inline-content:has(> .ProseMirror-trailingBreak):before`; + + const getSelector = ( + blockType: string | "default", + mustBeFocused = true + ) => { + const mustBeFocusedSelector = mustBeFocused + ? `[data-is-empty-and-focused]` + : ``; + + if (blockType === "default") { + return getBaseSelector(mustBeFocusedSelector); + } + + const blockTypeSelector = `[data-content-type="${blockType}"]`; + return getBaseSelector(mustBeFocusedSelector + blockTypeSelector); + }; + + for (const [blockType, placeholder] of Object.entries(placeholders)) { + const mustBeFocused = blockType === "default"; + + styleSheet.insertRule( + `${getSelector(blockType, mustBeFocused)}{ content: ${JSON.stringify( + placeholder + )}; }` + ); + + // For some reason, the placeholders which show when the block is focused + // take priority over ones which show depending on block type, so we need + // to make sure the block specific ones are also used when the block is + // focused. + if (!mustBeFocused) { + styleSheet.insertRule( + `${getSelector(blockType, true)}{ content: ${JSON.stringify( + placeholder + )}; }` + ); + } + } + + return { + destroy: () => { + document.head.removeChild(styleEl); + }, + }; + }, + props: { + // TODO: maybe also add placeholder for empty document ("e.g.: start writing..") + decorations: (state) => { + const { doc, selection } = state; + + if (!editor.isEditable) { + return; + } + + if (!selection.empty) { + return; + } + + const $pos = selection.$anchor; + const node = $pos.parent; + + if (node.content.size > 0) { + return null; + } + + const before = $pos.before(); + + const dec = Decoration.node(before, before + node.nodeSize, { + "data-is-empty-and-focused": "true", + }); + + return DecorationSet.create(doc, [dec]); + }, + }, + }); +}; diff --git a/packages/core/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts b/packages/core/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts index 4505a3aaa9..874c7e318c 100644 --- a/packages/core/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts +++ b/packages/core/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts @@ -1,4 +1,7 @@ +import type { Dictionary } from "../../i18n/dictionary"; + export type DefaultSuggestionItem = { + key: keyof Dictionary["slash_menu"]; title: string; onItemClick: () => void; subtext?: string; diff --git a/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts b/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts index a56363634e..8805c6a4d6 100644 --- a/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +++ b/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts @@ -83,95 +83,82 @@ export function getDefaultSlashMenuItems< if (checkDefaultBlockTypeInSchema("heading", editor)) { items.push( { - title: "Heading 1", onItemClick: () => { insertOrUpdateBlock(editor, { type: "heading", props: { level: 1 }, }); }, - subtext: "Used for a top-level heading", badge: formatKeyboardShortcut("Mod-Alt-1"), - aliases: ["h", "heading1", "h1"], - group: "Headings", + key: "heading", + ...editor.dictionary.slash_menu.heading, }, { - title: "Heading 2", onItemClick: () => { insertOrUpdateBlock(editor, { type: "heading", props: { level: 2 }, }); }, - subtext: "Used for key sections", badge: formatKeyboardShortcut("Mod-Alt-2"), - aliases: ["h2", "heading2", "subheading"], - group: "Headings", + key: "heading_2", + ...editor.dictionary.slash_menu.heading_2, }, { - title: "Heading 3", onItemClick: () => { insertOrUpdateBlock(editor, { type: "heading", props: { level: 3 }, }); }, - subtext: "Used for subsections and group headings", badge: formatKeyboardShortcut("Mod-Alt-3"), - aliases: ["h3", "heading3", "subheading"], - group: "Headings", + key: "heading_3", + ...editor.dictionary.slash_menu.heading_3, } ); } if (checkDefaultBlockTypeInSchema("numberedListItem", editor)) { items.push({ - title: "Numbered List", onItemClick: () => { insertOrUpdateBlock(editor, { type: "numberedListItem", }); }, - subtext: "Used to display a numbered list", badge: formatKeyboardShortcut("Mod-Shift-7"), - aliases: ["ol", "li", "list", "numberedlist", "numbered list"], - group: "Basic blocks", + key: "numbered_list", + ...editor.dictionary.slash_menu.numbered_list, }); } if (checkDefaultBlockTypeInSchema("bulletListItem", editor)) { items.push({ - title: "Bullet List", onItemClick: () => { insertOrUpdateBlock(editor, { type: "bulletListItem", }); }, - subtext: "Used to display an unordered list", badge: formatKeyboardShortcut("Mod-Shift-8"), - aliases: ["ul", "li", "list", "bulletlist", "bullet list"], - group: "Basic blocks", + key: "bullet_list", + ...editor.dictionary.slash_menu.bullet_list, }); } if (checkDefaultBlockTypeInSchema("paragraph", editor)) { items.push({ - title: "Paragraph", onItemClick: () => { insertOrUpdateBlock(editor, { type: "paragraph", }); }, - subtext: "Used for the body of your document", badge: formatKeyboardShortcut("Mod-Alt-0"), - aliases: ["p", "paragraph"], - group: "Basic blocks", + key: "paragraph", + ...editor.dictionary.slash_menu.paragraph, }); } if (checkDefaultBlockTypeInSchema("table", editor)) { items.push({ - title: "Table", onItemClick: () => { insertOrUpdateBlock(editor, { type: "table", @@ -188,16 +175,14 @@ export function getDefaultSlashMenuItems< }, }); }, - subtext: "Used for for tables", - aliases: ["table"], - group: "Advanced", badge: undefined, + key: "table", + ...editor.dictionary.slash_menu.table, }); } if (checkDefaultBlockTypeInSchema("image", editor)) { items.push({ - title: "Image", onItemClick: () => { const insertedBlock = insertOrUpdateBlock(editor, { type: "image", @@ -210,19 +195,8 @@ export function getDefaultSlashMenuItems< }) ); }, - subtext: "Insert an image", - aliases: [ - "image", - "imageUpload", - "upload", - "img", - "picture", - "media", - "url", - "drive", - "dropbox", - ], - group: "Media", + key: "image", + ...editor.dictionary.slash_menu.image, }); } diff --git a/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts b/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts index 8b1918d8e5..ac0be6cda9 100644 --- a/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts +++ b/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts @@ -350,7 +350,7 @@ export class TableHandlesView< }; destroy() { - this.pmView.dom.removeEventListener("mousedown", this.mouseMoveHandler); + this.pmView.dom.removeEventListener("mousemove", this.mouseMoveHandler); document.removeEventListener("dragover", this.dragOverHandler); document.removeEventListener("drop", this.dropHandler); diff --git a/packages/core/src/i18n/dictionary.ts b/packages/core/src/i18n/dictionary.ts new file mode 100644 index 0000000000..c93e6533c5 --- /dev/null +++ b/packages/core/src/i18n/dictionary.ts @@ -0,0 +1,17 @@ +// function scramble(dict: any) { +// const newDict: any = {} as any; + +import type { en } from "./locales"; + +// for (const key in dict) { +// if (typeof dict[key] === "object") { +// newDict[key] = scramble(dict[key]); +// } else { +// newDict[key] = dict[key].split("").reverse().join(""); +// } +// } + +// return newDict; +// } + +export type Dictionary = typeof en; diff --git a/packages/core/src/i18n/locales/en.ts b/packages/core/src/i18n/locales/en.ts new file mode 100644 index 0000000000..3efd049612 --- /dev/null +++ b/packages/core/src/i18n/locales/en.ts @@ -0,0 +1,192 @@ +export const en = { + slash_menu: { + heading: { + title: "Heading 1", + subtext: "Used for a top-level heading", + aliases: ["h", "heading1", "h1"], + group: "Headings", + }, + heading_2: { + title: "Heading 2", + subtext: "Used for key sections", + aliases: ["h2", "heading2", "subheading"], + group: "Headings", + }, + heading_3: { + title: "Heading 3", + subtext: "Used for subsections and group headings", + aliases: ["h3", "heading3", "subheading"], + group: "Headings", + }, + numbered_list: { + title: "Numbered List", + subtext: "Used to display a numbered list", + aliases: ["ol", "li", "list", "numberedlist", "numbered list"], + group: "Basic blocks", + }, + bullet_list: { + title: "Bullet List", + subtext: "Used to display an unordered list", + aliases: ["ul", "li", "list", "bulletlist", "bullet list"], + group: "Basic blocks", + }, + paragraph: { + title: "Paragraph", + subtext: "Used for the body of your document", + aliases: ["p", "paragraph"], + group: "Basic blocks", + }, + table: { + title: "Table", + subtext: "Used for for tables", + aliases: ["table"], + group: "Advanced", + }, + image: { + title: "Image", + subtext: "Insert an image", + aliases: [ + "image", + "imageUpload", + "upload", + "img", + "picture", + "media", + "url", + "drive", + "dropbox", + ], + group: "Media", + }, + }, + placeholders: { + default: "Enter text or type '/' for commands", + heading: "Heading", + bulletListItem: "List", + numberedListItem: "List", + }, + image: { + add_button: "Add Image", + }, + // from react package: + drag_handle: { + delete_menuitem: "Delete", + colors_menuitem: "Colors", + }, + table_handle: { + delete_column_menuitem: "Delete column", + delete_row_menuitem: "Delete row", + add_left_menuitem: "Add column left", + add_right_menuitem: "Add column right", + add_above_menuitem: "Add row above", + add_below_menuitem: "Add row below", + }, + suggestion_menu: { + no_items_title: "No items found", + loading: "Loading…", + }, + color_picker: { + text_title: "Text", + background_title: "Background", + colors: { + default: "Default", + gray: "Gray", + brown: "Brown", + red: "Red", + orange: "Orange", + yellow: "Yellow", + green: "Green", + blue: "Blue", + purple: "Purple", + pink: "Pink", + }, + }, + + formatting_toolbar: { + bold: { + tooltip: "Bold", + secondary_tooltip: "Mod+B", + }, + italic: { + tooltip: "Italic", + secondary_tooltip: "Mod+I", + }, + underline: { + tooltip: "Underline", + secondary_tooltip: "Mod+U", + }, + strike: { + tooltip: "Strike", + secondary_tooltip: "Mod+Shift+X", + }, + code: { + tooltip: "Code", + secondary_tooltip: "", + }, + colors: { + tooltip: "Colors", + }, + link: { + tooltip: "Create link", + secondary_tooltip: "Mod+K", + }, + image_caption: { + tooltip: "Edit caption", + input_placeholder: "Edit caption", + }, + image_replace: { + tooltip: "Replace image", + }, + nest: { + tooltip: "Nest block", + secondary_tooltip: "Tab", + }, + unnest: { + tooltip: "Unnest block", + secondary_tooltip: "Shift+Tab", + }, + align_left: { + tooltip: "Align text left", + }, + align_center: { + tooltip: "Align text center", + }, + align_right: { + tooltip: "Align text right", + }, + align_justify: { + tooltip: "Justify text", + }, + }, + image_panel: { + upload: { + title: "Upload", + file_placeholder: "Upload image", + upload_error: "Error: Upload failed", + }, + embed: { + title: "Embed", + embed_button: "Embed image", + url_placeholder: "Enter URL", + }, + }, + link_toolbar: { + delete: { + tooltip: "Remove link", + }, + edit: { + text: "Edit link", + tooltip: "Edit", + }, + open: { + tooltip: "Open in new tab", + }, + form: { + title_placeholder: "Edit title", + url_placeholder: "Edit URL", + }, + }, + generic: { + ctrl_shortcut: "Ctrl", + }, +}; diff --git a/packages/core/src/i18n/locales/index.ts b/packages/core/src/i18n/locales/index.ts new file mode 100644 index 0000000000..fe36955d21 --- /dev/null +++ b/packages/core/src/i18n/locales/index.ts @@ -0,0 +1 @@ +export * from "./en"; diff --git a/packages/core/src/i18n/locales/nl.ts b/packages/core/src/i18n/locales/nl.ts new file mode 100644 index 0000000000..be0cf48363 --- /dev/null +++ b/packages/core/src/i18n/locales/nl.ts @@ -0,0 +1,193 @@ +import type { Dictionary } from "../dictionary"; + +export const nl: Dictionary = { + slash_menu: { + heading: { + title: "Kop 1", + subtext: "Gebruikt voor een hoofdkop", + aliases: ["h", "kop1", "h1"], + group: "Koppen", + }, + heading_2: { + title: "Kop 2", + subtext: "Gebruikt voor belangrijke secties", + aliases: ["h2", "kop2", "subkop"], + group: "Koppen", + }, + heading_3: { + title: "Kop 3", + subtext: "Gebruikt voor subsecties en groepskoppen", + aliases: ["h3", "kop3", "subkop"], + group: "Koppen", + }, + numbered_list: { + title: "Genummerde Lijst", + subtext: "Gebruikt om een genummerde lijst weer te geven", + aliases: ["ol", "li", "lijst", "genummerdelijst", "genummerde lijst"], + group: "Basisblokken", + }, + bullet_list: { + title: "Puntenlijst", + subtext: "Gebruikt om een ongeordende lijst weer te geven", + aliases: ["ul", "li", "lijst", "puntenlijst", "punten lijst"], + group: "Basisblokken", + }, + paragraph: { + title: "Paragraaf", + subtext: "Gebruikt voor de hoofdtekst van uw document", + aliases: ["p", "paragraaf"], + group: "Basisblokken", + }, + table: { + title: "Tabel", + subtext: "Gebruikt voor tabellen", + aliases: ["tabel"], + group: "Geavanceerd", + }, + image: { + title: "Afbeelding", + subtext: "Voeg een afbeelding in", + aliases: [ + "afbeelding", + "imageUpload", + "upload", + "img", + "foto", + "media", + "url", + "drive", + "dropbox", + ], + group: "Media", + }, + }, + placeholders: { + default: "Voer tekst in of type '/' voor commando's", + heading: "Kop", + bulletListItem: "Lijst", + numberedListItem: "Lijst", + }, + image: { + add_button: "Afbeelding toevoegen", + }, + // from react package: + drag_handle: { + delete_menuitem: "Verwijder", + colors_menuitem: "Kleuren", + }, + table_handle: { + delete_column_menuitem: "Verwijder kolom", + delete_row_menuitem: "Verwijder rij", + add_left_menuitem: "Voeg kolom links toe", + add_right_menuitem: "Voeg kolom rechts toe", + add_above_menuitem: "Voeg rij boven toe", + add_below_menuitem: "Voeg rij onder toe", + }, + suggestion_menu: { + no_items_title: "Geen items gevonden", + loading: "Laden…", + }, + color_picker: { + text_title: "Tekst", + background_title: "Achtergrond", + colors: { + default: "Standaard", + gray: "Grijs", + brown: "Bruin", + red: "Rood", + orange: "Oranje", + yellow: "Geel", + green: "Groen", + blue: "Blauw", + purple: "Paars", + pink: "Roze", + }, + }, + formatting_toolbar: { + bold: { + tooltip: "Vet", + secondary_tooltip: "Mod+B", + }, + italic: { + tooltip: "Cursief", + secondary_tooltip: "Mod+I", + }, + underline: { + tooltip: "Onderstrepen", + secondary_tooltip: "Mod+U", + }, + strike: { + tooltip: "Doorstrepen", + secondary_tooltip: "Mod+Shift+X", + }, + code: { + tooltip: "Code", + secondary_tooltip: "", + }, + colors: { + tooltip: "Kleuren", + }, + link: { + tooltip: "Maak link", + secondary_tooltip: "Mod+K", + }, + image_caption: { + tooltip: "Bewerk onderschrift", + input_placeholder: "Bewerk onderschrift", + }, + image_replace: { + tooltip: "Vervang afbeelding", + }, + nest: { + tooltip: "Nest blok", + secondary_tooltip: "Tab", + }, + unnest: { + tooltip: "Ontnest blok", + secondary_tooltip: "Shift+Tab", + }, + align_left: { + tooltip: "Tekst links uitlijnen", + }, + align_center: { + tooltip: "Tekst centreren", + }, + align_right: { + tooltip: "Tekst rechts uitlijnen", + }, + align_justify: { + tooltip: "Tekst uitvullen", + }, + }, + image_panel: { + upload: { + title: "Upload", + file_placeholder: "Upload afbeelding", + upload_error: "Fout: Upload mislukt", + }, + embed: { + title: "Insluiten", + embed_button: "Insluiten afbeelding", + url_placeholder: "Voer URL in", + }, + }, + link_toolbar: { + delete: { + tooltip: "Verwijder link", + }, + edit: { + text: "Bewerk link", + tooltip: "Bewerk", + }, + open: { + tooltip: "Open in nieuw tabblad", + }, + form: { + title_placeholder: "Bewerk titel", + url_placeholder: "Bewerk URL", + }, + }, + generic: { + ctrl_shortcut: "Ctrl", + }, +}; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 5a202f72bd..1a70105d11 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,3 +1,4 @@ +import * as locales from "./i18n/locales"; export * from "./api/exporters/html/externalHTMLExporter"; export * from "./api/exporters/html/internalHTMLSerializer"; export * from "./api/testUtil"; @@ -25,4 +26,6 @@ export * from "./util/string"; export * from "./api/nodeConversions/nodeConversions"; export * from "./api/testUtil/partialBlockTestUtil"; export * from "./extensions/UniqueID/UniqueID"; +export * from "./i18n/dictionary"; export { UnreachableCaseError } from "./util/typescript"; +export { locales }; diff --git a/packages/core/src/util/browser.ts b/packages/core/src/util/browser.ts index e5fcf8ac71..9ecdf3250d 100644 --- a/packages/core/src/util/browser.ts +++ b/packages/core/src/util/browser.ts @@ -4,11 +4,11 @@ export const isAppleOS = () => (/AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent))); -export function formatKeyboardShortcut(shortcut: string) { +export function formatKeyboardShortcut(shortcut: string, ctrlText = "Ctrl") { if (isAppleOS()) { return shortcut.replace("Mod", "⌘"); } else { - return shortcut.replace("Mod", "Ctrl"); + return shortcut.replace("Mod", ctrlText); } } diff --git a/packages/dev-scripts/examples/template-react/package.json.template.tsx b/packages/dev-scripts/examples/template-react/package.json.template.tsx index 5b391fab85..aa21a45bbc 100644 --- a/packages/dev-scripts/examples/template-react/package.json.template.tsx +++ b/packages/dev-scripts/examples/template-react/package.json.template.tsx @@ -13,8 +13,11 @@ const template = (project: Project) => ({ lint: "eslint . --max-warnings 0", }, dependencies: { - "@blocknote/core": "^0.12.0", - "@blocknote/react": "^0.12.0", + "@blocknote/core": "^0.12.1", + "@blocknote/react": "^0.12.2", + "@blocknote/ariakit": "^0.12.2", + "@blocknote/mantine": "^0.12.2", + "@blocknote/shadcn": "^0.12.2", react: "^18.2.0", "react-dom": "^18.2.0", ...(project.config?.dependencies || {}), diff --git a/packages/mantine/package.json b/packages/mantine/package.json new file mode 100644 index 0000000000..f656fbff26 --- /dev/null +++ b/packages/mantine/package.json @@ -0,0 +1,86 @@ +{ + "name": "@blocknote/mantine", + "homepage": "https://github.com/TypeCellOS/BlockNote", + "private": false, + "license": "MPL-2.0", + "version": "0.12.2", + "files": [ + "dist", + "types", + "src" + ], + "keywords": [ + "react", + "javascript", + "editor", + "typescript", + "prosemirror", + "wysiwyg", + "rich-text-editor", + "notion", + "yjs", + "block-based", + "tiptap" + ], + "description": "A \"Notion-style\" block-based extensible text editor built on top of Prosemirror and Tiptap.", + "type": "module", + "source": "src/index.tsx", + "types": "./types/src/index.d.ts", + "main": "./dist/blocknote-mantine.umd.cjs", + "module": "./dist/blocknote-mantine.js", + "exports": { + ".": { + "types": "./types/src/index.d.ts", + "import": "./dist/blocknote-mantine.js", + "require": "./dist/blocknote-mantine.umd.cjs" + }, + "./style.css": { + "import": "./dist/style.css", + "require": "./dist/style.css" + } + }, + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "build-bundled": "tsc && vite build --config vite.config.bundled.ts && git checkout tmp-releases && rm -rf ../../release && mv ../../release-tmp ../../release", + "preview": "vite preview", + "lint": "eslint src --max-warnings 0", + "clean": "rimraf dist && rimraf types" + }, + "dependencies": { + "@blocknote/core": "*", + "@blocknote/react": "*", + "@mantine/core": "^7.5.0", + "@mantine/hooks": "^7.5.0", + "@mantine/utils": "^6.0.21", + "react": "^18", + "react-dom": "^18", + "react-icons": "^4.3.1" + }, + "devDependencies": { + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", + "@vitejs/plugin-react": "^4.0.4", + "eslint": "^8.10.0", + "prettier": "^2.7.1", + "rimraf": "^5.0.5", + "rollup-plugin-webpack-stats": "^0.2.2", + "typescript": "^5.3.3", + "vite": "^4.4.8", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-externalize-deps": "^0.7.0" + }, + "peerDependencies": { + "react": "^18", + "react-dom": "^18" + }, + "eslintConfig": { + "extends": [ + "../../.eslintrc.js" + ] + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + } +} diff --git a/packages/mantine/src/form/TextInput.tsx b/packages/mantine/src/form/TextInput.tsx new file mode 100644 index 0000000000..db4a76a1c6 --- /dev/null +++ b/packages/mantine/src/form/TextInput.tsx @@ -0,0 +1,39 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const TextInput = forwardRef< + HTMLInputElement, + ComponentProps["Generic"]["Form"]["TextInput"] +>((props, ref) => { + const { + className, + name, + label, + icon, + value, + autoFocus, + placeholder, + onKeyDown, + onChange, + onSubmit, + } = props; + + return ( + + ); +}); diff --git a/packages/mantine/src/index.tsx b/packages/mantine/src/index.tsx new file mode 100644 index 0000000000..285b27397a --- /dev/null +++ b/packages/mantine/src/index.tsx @@ -0,0 +1,110 @@ +import { + BlockNoteViewRaw, + Components, + ComponentsContext, +} from "@blocknote/react"; +import { MantineProvider } from "@mantine/core"; +import { ComponentProps } from "react"; + +import { TextInput } from "./form/TextInput"; +import { + Menu, + MenuDivider, + MenuDropdown, + MenuItem, + MenuLabel, + MenuTrigger, +} from "./menu/Menu"; +import { Panel } from "./panel/Panel"; +import { PanelButton } from "./panel/PanelButton"; +import { PanelFileInput } from "./panel/PanelFileInput"; +import { PanelTab } from "./panel/PanelTab"; +import { PanelTextInput } from "./panel/PanelTextInput"; +import { Popover, PopoverContent, PopoverTrigger } from "./popover/Popover"; +import { SideMenu } from "./sideMenu/SideMenu"; +import { SideMenuButton } from "./sideMenu/SideMenuButton"; +import { SuggestionMenu } from "./suggestionMenu/SuggestionMenu"; +import { SuggestionMenuItem } from "./suggestionMenu/SuggestionMenuItem"; +import { SuggestionMenuEmptyItem } from "./suggestionMenu/SuggestionMenuEmptyItem"; +import { SuggestionMenuLabel } from "./suggestionMenu/SuggestionMenuLabel"; +import { SuggestionMenuLoader } from "./suggestionMenu/SuggestionMenuLoader"; +import { TableHandle } from "./tableHandle/TableHandle"; +import { Toolbar } from "./toolbar/Toolbar"; +import { ToolbarButton } from "./toolbar/ToolbarButton"; +import { ToolbarSelect } from "./toolbar/ToolbarSelect"; + +import "./style.css"; + +export const components: Components = { + FormattingToolbar: { + Root: Toolbar, + Button: ToolbarButton, + Select: ToolbarSelect, + }, + ImagePanel: { + Root: Panel, + Button: PanelButton, + FileInput: PanelFileInput, + TabPanel: PanelTab, + TextInput: PanelTextInput, + }, + LinkToolbar: { + Root: Toolbar, + Button: ToolbarButton, + }, + SideMenu: { + Root: SideMenu, + Button: SideMenuButton, + }, + SuggestionMenu: { + Root: SuggestionMenu, + Item: SuggestionMenuItem, + EmptyItem: SuggestionMenuEmptyItem, + Label: SuggestionMenuLabel, + Loader: SuggestionMenuLoader, + }, + TableHandle: { + Root: TableHandle, + }, + Generic: { + Form: { + Root: (props) =>
{props.children}
, + TextInput: TextInput, + }, + Menu: { + Root: Menu, + Trigger: MenuTrigger, + Dropdown: MenuDropdown, + Divider: MenuDivider, + Label: MenuLabel, + Item: MenuItem, + }, + Popover: { + Root: Popover, + Trigger: PopoverTrigger, + Content: PopoverContent, + }, + }, +}; + +const mantineTheme = { + // Removes button press effect + activeClassName: "", +}; + +export const BlockNoteView = ( + // TODO: Fix typing + props: ComponentProps> +) => { + return ( + + {/* `cssVariablesSelector` scopes Mantine CSS variables to only the editor, */} + {/* as proposed here: https://github.com/orgs/mantinedev/discussions/5685 */} + + + + + ); +}; diff --git a/packages/react/src/editor/mantineStyles.css b/packages/mantine/src/mantineStyles.css similarity index 100% rename from packages/react/src/editor/mantineStyles.css rename to packages/mantine/src/mantineStyles.css diff --git a/packages/mantine/src/menu/Menu.tsx b/packages/mantine/src/menu/Menu.tsx new file mode 100644 index 0000000000..16d14aeea6 --- /dev/null +++ b/packages/mantine/src/menu/Menu.tsx @@ -0,0 +1,243 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { + createContext, + forwardRef, + useCallback, + useContext, + useRef, + useState, +} from "react"; +import { HiChevronRight } from "react-icons/hi"; + +const SubMenuContext = createContext< + | { + onTriggerMouseOver: () => void; + onTriggerMouseLeave: () => void; + onMenuMouseOver: () => void; + onMenuMouseLeave: () => void; + } + | undefined +>(undefined); + +// https://github.com/orgs/mantinedev/discussions/2307 +// Mantine does not officially support sub menus, so we have to use a workaround +// which uses an unconventional nesting structure: +// +// Conventional nesting structure (used by Ariakit/ShadCN): +// +// +// Find +// +// +// Undo +// Redo +// +// +// Find +// +// +// Find Next +// Find Previous +// +// +// +// +// +// Required structure for Mantine: +// +// +// Find +// +// +// Undo +// Redo +// +// +// +//
Find
+//
+// +// Find Next +// Find Previous +// +//
+//
+//
+//
+const SubMenu = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Root"] +>((props, ref) => { + const { + children, + onOpenChange, + position, + // sub + } = props; + const [opened, setOpened] = useState(false); + + const menuCloseTimer = useRef | undefined>(); + + const mouseLeave = useCallback(() => { + if (menuCloseTimer.current) { + clearTimeout(menuCloseTimer.current); + } + menuCloseTimer.current = setTimeout(() => { + setOpened(false); + }, 250); + }, []); + + const mouseOver = useCallback(() => { + if (menuCloseTimer.current) { + clearTimeout(menuCloseTimer.current); + } + + setOpened(true); + }, []); + + return ( + + + onOpenChange?.(false)} + onOpen={() => onOpenChange?.(true)} + position={position}> + {children} + + + + ); +}); + +export const Menu = (props: ComponentProps["Generic"]["Menu"]["Root"]) => { + const { children, onOpenChange, position, sub } = props; + + if (sub) { + return ; + } + + return ( + onOpenChange?.(false)} + onOpen={() => onOpenChange?.(true)} + position={position}> + {children} + + ); +}; + +export const MenuItem = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Item"] +>((props, ref) => { + const { className, children, icon, checked, subTrigger, onClick, ...rest } = + props; + + const ctx = useContext(SubMenuContext); + + if (subTrigger) { + return ( +
+ {children} + +
+ ); + } + + const onMouseLeave = subTrigger ? ctx!.onTriggerMouseLeave : undefined; + const onMouseOver = subTrigger ? ctx!.onTriggerMouseOver : undefined; + + return ( + + ) : checked === false ? ( +
+ ) : null + } + onMouseOver={onMouseOver} + onMouseLeave={onMouseLeave} + onClick={onClick} + {...rest}> + {children} + + ); +}); + +export const MenuTrigger = ( + props: ComponentProps["Generic"]["Menu"]["Trigger"] +) => { + const { + children, + // sub + } = props; + + return {children}; +}; + +export const MenuDropdown = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Dropdown"] +>((props, ref) => { + const { className, children, sub } = props; + + const ctx = useContext(SubMenuContext); + + return ( + + {children} + + ); +}); + +export const MenuDivider = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Divider"] +>((props, ref) => { + const { className } = props; + + return ; +}); + +export const MenuLabel = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Menu"]["Label"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/panel/Panel.tsx b/packages/mantine/src/panel/Panel.tsx new file mode 100644 index 0000000000..78a29f6231 --- /dev/null +++ b/packages/mantine/src/panel/Panel.tsx @@ -0,0 +1,47 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const Panel = forwardRef< + HTMLDivElement, + ComponentProps["ImagePanel"]["Root"] +>((props, ref) => { + const { + className, + tabs, + defaultOpenTab, + openTab, + setOpenTab, + loading, + // setLoading, + } = props; + + return ( + + + {loading && } + + + {tabs.map((tab) => ( + + {tab.name} + + ))} + + + {tabs.map((tab) => ( + + {tab.tabPanel} + + ))} + + + ); +}); diff --git a/packages/mantine/src/panel/PanelButton.tsx b/packages/mantine/src/panel/PanelButton.tsx new file mode 100644 index 0000000000..37909ce62a --- /dev/null +++ b/packages/mantine/src/panel/PanelButton.tsx @@ -0,0 +1,22 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelButton = forwardRef< + HTMLButtonElement, + ComponentProps["ImagePanel"]["Button"] +>((props, ref) => { + const { className, children, onClick, ...rest } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/panel/PanelFileInput.tsx b/packages/mantine/src/panel/PanelFileInput.tsx new file mode 100644 index 0000000000..5c38c138a4 --- /dev/null +++ b/packages/mantine/src/panel/PanelFileInput.tsx @@ -0,0 +1,23 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelFileInput = forwardRef< + HTMLButtonElement, + ComponentProps["ImagePanel"]["FileInput"] +>((props, ref) => { + const { className, value, placeholder, onChange, ...rest } = props; + + return ( + + ); +}); diff --git a/packages/mantine/src/panel/PanelTab.tsx b/packages/mantine/src/panel/PanelTab.tsx new file mode 100644 index 0000000000..58ed2aba46 --- /dev/null +++ b/packages/mantine/src/panel/PanelTab.tsx @@ -0,0 +1,15 @@ +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelTab = forwardRef< + HTMLDivElement, + ComponentProps["ImagePanel"]["TabPanel"] +>((props, ref) => { + const { className, children } = props; + + return ( +
+ {children} +
+ ); +}); diff --git a/packages/mantine/src/panel/PanelTextInput.tsx b/packages/mantine/src/panel/PanelTextInput.tsx new file mode 100644 index 0000000000..59f6f9b884 --- /dev/null +++ b/packages/mantine/src/panel/PanelTextInput.tsx @@ -0,0 +1,24 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const PanelTextInput = forwardRef< + HTMLInputElement, + ComponentProps["ImagePanel"]["TextInput"] +>((props, ref) => { + const { className, value, placeholder, onKeyDown, onChange } = props; + + return ( + + ); +}); diff --git a/packages/mantine/src/popover/Popover.tsx b/packages/mantine/src/popover/Popover.tsx new file mode 100644 index 0000000000..ccc1a74aeb --- /dev/null +++ b/packages/mantine/src/popover/Popover.tsx @@ -0,0 +1,41 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const Popover = ( + props: ComponentProps["Generic"]["Popover"]["Root"] +) => { + const { children, opened, position } = props; + + return ( + + {children} + + ); +}; + +export const PopoverTrigger = ( + props: ComponentProps["Generic"]["Popover"]["Trigger"] +) => { + const { children } = props; + + return {children}; +}; + +export const PopoverContent = forwardRef< + HTMLDivElement, + ComponentProps["Generic"]["Popover"]["Content"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/sideMenu/SideMenu.tsx b/packages/mantine/src/sideMenu/SideMenu.tsx new file mode 100644 index 0000000000..7a233730d8 --- /dev/null +++ b/packages/mantine/src/sideMenu/SideMenu.tsx @@ -0,0 +1,17 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SideMenu = forwardRef< + HTMLDivElement, + ComponentProps["SideMenu"]["Root"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/sideMenu/SideMenuButton.tsx b/packages/mantine/src/sideMenu/SideMenuButton.tsx new file mode 100644 index 0000000000..329f0baf4f --- /dev/null +++ b/packages/mantine/src/sideMenu/SideMenuButton.tsx @@ -0,0 +1,30 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SideMenuButton = forwardRef< + HTMLButtonElement, + ComponentProps["SideMenu"]["Button"] +>((props, ref) => { + const { className, children, icon, onClick, ...rest } = props; + + if (icon) { + return ( + + {icon} + + ); + } + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/style.css b/packages/mantine/src/style.css new file mode 100644 index 0000000000..3f9aa96923 --- /dev/null +++ b/packages/mantine/src/style.css @@ -0,0 +1,490 @@ +@import url("@blocknote/react/style.css"); +@import url("./mantineStyles.css"); + +/* Mantine base styles*/ + +/* Mantine Badge component base styles */ +.bn-container .mantine-Badge-root { + background-color: var(--bn-colors-tooltip-background); + color: var(--bn-colors-tooltip-text); +} + +/* Mantine FileInput component base styles */ +.bn-container .mantine-FileInput-input { + align-items: center; + background-color: var(--bn-colors-menu-background); + border: none; + border-radius: 4px; + color: var(--bn-colors-menu-text); + display: flex; + flex-direction: row; + justify-content: center; +} + +.bn-container .mantine-FileInput-input:hover { + background-color: var(--bn-colors-hovered-background); +} + +.bn-container .mantine-FileInput-wrapper { + border: solid var(--bn-colors-border) 1px; + border-radius: 4px; +} + +.bn-container .mantine-InputPlaceholder-placeholder { + color: var(--bn-colors-menu-text); + font-weight: 600; +} + +/* Mantine Menu component base styles */ +.bn-container .mantine-Menu-dropdown { + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + box-sizing: border-box; + color: var(--bn-colors-menu-text); + padding: 2px; + overflow: auto; +} + +.bn-container .mantine-Menu-label { + background-color: var(--bn-colors-menu-background); + color: var(--bn-colors-menu-text); +} + +.bn-container .mantine-Menu-item { + background-color: var(--bn-colors-menu-background); + border: none; + border-radius: var(--bn-border-radius-small); + color: var(--bn-colors-menu-text); +} + +.bn-container .mantine-Menu-item[data-hovered] { + background-color: var(--bn-colors-hovered-background); + border: none; + color: var(--bn-colors-hovered-text); +} + +/* Mantine Popover component base styles */ +.bn-container .mantine-Popover-dropdown { + background-color: transparent; + border: none; + border-radius: 0; + box-shadow: none; + padding: 0; +} + +/* Mantine Tabs component base styles */ +.bn-container .mantine-Tabs-root { + width: 100%; + background-color: var(--bn-colors-menu-background); +} + +.bn-container .mantine-Tabs-list:before { + border-color: var(--bn-colors-hovered-background); +} + +.bn-container .mantine-Tabs-tab { + color: var(--bn-colors-menu-text); + border-color: var(--bn-colors-hovered-background); +} + +.bn-container .mantine-Tabs-tab:hover { + background-color: var(--bn-colors-hovered-background); + border-color: var(--bn-colors-hovered-background); + color: var(--bn-colors-hovered-text); +} + +.bn-container .mantine-Tabs-tab[data-active], +.bn-container .mantine-Tabs-tab[data-active]:hover { + border-color: var(--bn-colors-menu-text); + color: var(--bn-colors-menu-text); +} + +.bn-container .mantine-Tabs-panel { + padding: 8px; +} + +/* Mantine TextInput component base styles */ +.bn-container .mantine-TextInput-input { + background-color: var(--bn-colors-menu-background); + border: solid var(--bn-colors-border) 1px; + border-radius: 4px; + color: var(--bn-colors-menu-text); + height: 32px; +} + +/* Mantine Tooltip component base styles */ +.bn-container .mantine-Tooltip-tooltip { + background-color: transparent; + border: none; + border-radius: 0; + box-shadow: none; + padding: 0; +} + +/* UI element styling */ + +/* Select styling */ +.bn-select { + overflow: auto; +} + +/* Toolbar styling */ +.bn-toolbar { + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + flex-wrap: nowrap; + gap: 2px; + padding: 2px; + width: fit-content; +} + +.bn-toolbar:empty { + display: none; +} + +.bn-toolbar .mantine-Button-root, +.bn-toolbar .mantine-ActionIcon-root { + background-color: var(--bn-colors-menu-background); + border: none; + border-radius: var(--bn-border-radius-small); + color: var(--bn-colors-menu-text); +} + +.bn-toolbar .mantine-Button-root:hover, +.bn-toolbar .mantine-ActionIcon-root:hover { + background-color: var(--bn-colors-hovered-background); + border: none; + color: var(--bn-colors-hovered-text); +} + +.bn-toolbar .mantine-Button-root[data-selected], +.bn-toolbar .mantine-ActionIcon-root[data-selected] { + background-color: var(--bn-colors-selected-background); + border: none; + color: var(--bn-colors-selected-text); +} + +.bn-toolbar .mantine-Button-root[data-disabled], +.bn-toolbar .mantine-ActionIcon-root[data-disabled] { + background-color: var(--bn-colors-disabled-background); + border: none; + color: var(--bn-colors-disabled-text); +} + +.bn-toolbar .mantine-Menu-item { + font-size: 12px; + height: 30px; +} + +.bn-toolbar .mantine-Menu-item:hover { + background-color: var(--bn-colors-hovered-background); +} + +.bn-container .bn-form-popover { + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + color: var(--bn-colors-menu-text); + gap: 4px; + min-width: 145px; + padding: 2px; +} + +.bn-form-popover .mantine-TextInput-root, +.bn-form-popover .mantine-FileInput-root { + width: 300px; +} + +.bn-form-popover .mantine-TextInput-wrapper, +.bn-form-popover .mantine-FileInput-wrapper { + padding: 0; + border-radius: 4px; +} + +.bn-form-popover .mantine-TextInput-wrapper:hover { + background-color: var(--bn-colors-hovered-background); +} + +.bn-form-popover .mantine-TextInput-input, +.bn-form-popover .mantine-FileInput-input { + border: none; + font-size: 12px; +} + +.bn-form-popover .mantine-FileInput-input:hover { + background-color: var(--bn-colors-hovered-background); +} + +.bn-form-popover .mantine-FileInput-section[data-position="left"] { + color: var(--bn-colors-menu-text); +} + +.bn-form-popover .mantine-FileInput-placeholder { + color: var(--bn-colors-menu-text); +} + +/* Suggestion Menu styling*/ + +/*TODO: Make sure there's a clear split between copied Mantine Menu styles and + additional BlockNote styles*/ + +/* Base styles for Suggestion Menus, copied from the Mantine Menu component. */ +/* Unfortunately necessary, as we can't use a Menu.Dropdown component on its + own. */ +/* https://github.com/mantinedev/mantine/blob/e3e3bb834de1f2f75a27dbc757dc0a2fc6a6cba8/packages/%40mantine/core/src/components/Menu/Menu.module.css */ +.bn-suggestion-menu { + max-height: 100%; + position: relative; + box-shadow: var(--mantine-shadow-md); + border: calc(0.0625rem * var(--mantine-scale)) solid + var(--mantine-color-gray-2); + border-radius: var(--mantine-radius-default); + padding: 4px; +} + +.bn-suggestion-menu-label { + color: var(--mantine-color-dimmed); + font-weight: 500; + font-size: var(--mantine-font-size-xs); + padding: calc(var(--mantine-spacing-xs) / 2) var(--mantine-spacing-sm); + cursor: default; +} + +.bn-suggestion-menu-item { + font-size: var(--mantine-font-size-sm); + width: 100%; + padding: calc(var(--mantine-spacing-xs) / 1.5) var(--mantine-spacing-sm); + border-radius: var(--popover-radius, var(--mantine-radius-default)); + color: var(--menu-item-color, var(--mantine-color-text)); + display: flex; + align-items: center; + user-select: none; + + &:where([data-disabled], :disabled) { + color: var(--mantine-color-dimmed); + opacity: 0.6; + pointer-events: none; + } + + &:where([data-hovered]) { + } +} + +.bn-mt-suggestion-menu-item-body { + flex: 1; +} + +.bn-mt-suggestion-menu-item-section { + display: flex; + justify-content: center; + align-items: center; + + &:where([data-position="left"]) { + margin-inline-end: var(--mantine-spacing-xs); + } + + &:where([data-position="right"]) { + margin-inline-start: var(--mantine-spacing-xs); + } +} + +.bn-suggestion-menu { + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + box-sizing: border-box; + color: var(--bn-colors-menu-text); + overflow-y: auto; + padding: 2px; +} + +.bn-suggestion-menu-item { + cursor: pointer; + height: 52px; +} + +.bn-suggestion-menu-item[data-hovered] { + background-color: var(--bn-colors-hovered-background); +} + +.bn-mt-suggestion-menu-item-section { + color: var(--bn-colors-tooltip-text); +} + +.bn-mt-suggestion-menu-item-section[data-position="left"] { + background-color: var(--bn-colors-tooltip-background); + border-radius: var(--bn-border-radius-small); + padding: 8px; +} + +.bn-mt-suggestion-menu-item-body { + align-items: stretch; + color: var(--bn-colors-menu-text); + display: flex; + flex: 1; + flex-direction: column; + justify-content: flex-start; + padding-right: 16px; +} + +.bn-mt-suggestion-menu-item-title { + line-height: 20px; + font-weight: 500; + font-size: 14px; + margin: 0; + padding: 0; +} + +.bn-mt-suggestion-menu-item-subtitle { + line-height: 16px; + font-size: 10px; + margin: 0; + padding: 0; +} + +.bn-suggestion-menu-label { + color: var(--bn-colors-hovered-text); +} + +.bn-suggestion-menu-loader { + height: 20px; + width: 100%; +} + +.bn-suggestion-menu-loader span { + background-color: var(--bn-colors-side-menu); +} + +/* Side Menu styling */ +.bn-side-menu { + background-color: transparent; + overflow: visible; +} + +.bn-side-menu .mantine-Menu-item, .bn-table-handle-menu .mantine-Menu-item { + font-size: 12px; + height: 30px; +} + +.bn-side-menu .mantine-UnstyledButton-root:not(.mantine-Menu-item) { + background-color: transparent; +} + +.bn-side-menu .mantine-UnstyledButton-root:hover { + background-color: var(--bn-colors-hovered-background); +} + +.bn-side-menu .mantine-UnstyledButton-root:not(.mantine-Menu-item) svg { + background-color: transparent; + color: var(--bn-colors-side-menu); + height: 22px; + width: 22px; +} + +.bn-side-menu > [draggable="true"] { + display: flex; +} + +.bn-side-menu .mantine-Menu-dropdown { + min-width: 100px; + padding: 2px; + position: absolute; +} + +/* Image Panel styling*/ +.bn-panel { + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + padding: 2px; + width: 500px; +} + +.bn-panel .bn-tab-panel { + align-items: center; + display: flex; + flex-direction: column; + gap: 8px; + width: 100%; +} + +.bn-panel .mantine-TextInput-root, +.bn-panel .mantine-FileInput-root { + width: 100%; +} + +.bn-panel .mantine-Button-root { + background-color: var(--bn-colors-menu-background); + border: solid var(--bn-colors-border) 1px; + border-radius: var(--bn-border-radius-small); + color: var(--bn-colors-menu-text); + height: 32px; + width: 60%; +} + +.bn-panel .mantine-Button-root:hover { + background-color: var(--bn-colors-hovered-background); +} + +.bn-panel.mantine-Text-root { + text-align: center; +} + +/* Table Handle styling */ +.bn-table-handle { + align-items: center; + background-color: var(--bn-colors-menu-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-small); + box-shadow: var(--bn-shadow-light); + color: var(--bn-colors-side-menu); + cursor: pointer; + display: flex; + justify-content: center; + overflow: visible; + padding: 0; +} + +.bn-table-handle svg { + margin-inline: -4px; +} + +.bn-table-handle:hover, +.bn-table-handle-dragging { + background-color: var(--bn-colors-hovered-background); +} + +/* Drag Handle & Table Handle Menu styling */ +.bn-container .bn-drag-handle-menu { + overflow: visible; +} + +/* Tooltip styling */ +.bn-tooltip { + background-color: var(--bn-colors-tooltip-background); + border: var(--bn-border); + border-radius: var(--bn-border-radius-medium); + box-shadow: var(--bn-shadow-medium); + color: var(--bn-colors-tooltip-text); + padding: 4px 10px; + text-align: center; +} + +/* Additional menu styles */ +.bn-tick-space { + padding: 0; + width: 20px; +} + +.bn-mt-sub-menu-item > .mantine-Menu-itemLabel > div:not(.mantine-Menu-dropdown) { + align-items: center; + display: flex; + justify-content: space-between; +} diff --git a/packages/mantine/src/suggestionMenu/SuggestionMenu.tsx b/packages/mantine/src/suggestionMenu/SuggestionMenu.tsx new file mode 100644 index 0000000000..4c0e5a6db7 --- /dev/null +++ b/packages/mantine/src/suggestionMenu/SuggestionMenu.tsx @@ -0,0 +1,17 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenu = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Root"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/suggestionMenu/SuggestionMenuEmptyItem.tsx b/packages/mantine/src/suggestionMenu/SuggestionMenuEmptyItem.tsx new file mode 100644 index 0000000000..3e88792d86 --- /dev/null +++ b/packages/mantine/src/suggestionMenu/SuggestionMenuEmptyItem.tsx @@ -0,0 +1,19 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenuEmptyItem = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["EmptyItem"] +>((props, ref) => { + const { className, children } = props; + + return ( + + + {children} + + + ); +}); diff --git a/packages/mantine/src/suggestionMenu/SuggestionMenuItem.tsx b/packages/mantine/src/suggestionMenu/SuggestionMenuItem.tsx new file mode 100644 index 0000000000..bc622bb073 --- /dev/null +++ b/packages/mantine/src/suggestionMenu/SuggestionMenuItem.tsx @@ -0,0 +1,67 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef, useCallback } from "react"; + +export const SuggestionMenuItem = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Item"] +>((props, ref) => { + const { + className, + title, + subtext, + // group, + icon, + badge, + // aliases, + // onItemClick, + isSelected, + setSelected, + onClick, + } = props; + + const handleMouseLeave = useCallback(() => { + setSelected?.(false); + }, [setSelected]); + + const handleMouseEnter = useCallback(() => { + setSelected?.(true); + }, [setSelected]); + + return ( + + {icon && ( + + {icon} + + )} + + + {title} + + + {subtext} + + + {badge && ( + + {badge} + + )} + + ); +}); diff --git a/packages/mantine/src/suggestionMenu/SuggestionMenuLabel.tsx b/packages/mantine/src/suggestionMenu/SuggestionMenuLabel.tsx new file mode 100644 index 0000000000..9c7178cc9b --- /dev/null +++ b/packages/mantine/src/suggestionMenu/SuggestionMenuLabel.tsx @@ -0,0 +1,17 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenuLabel = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Label"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/suggestionMenu/SuggestionMenuLoader.tsx b/packages/mantine/src/suggestionMenu/SuggestionMenuLoader.tsx new file mode 100644 index 0000000000..c68760f42e --- /dev/null +++ b/packages/mantine/src/suggestionMenu/SuggestionMenuLoader.tsx @@ -0,0 +1,17 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const SuggestionMenuLoader = forwardRef< + HTMLDivElement, + ComponentProps["SuggestionMenu"]["Loader"] +>((props, ref) => { + const { className, children } = props; + + return ( + + {children} + + ); +}); diff --git a/packages/mantine/src/tableHandle/TableHandle.tsx b/packages/mantine/src/tableHandle/TableHandle.tsx new file mode 100644 index 0000000000..08ed50271e --- /dev/null +++ b/packages/mantine/src/tableHandle/TableHandle.tsx @@ -0,0 +1,30 @@ +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const TableHandle = forwardRef< + HTMLButtonElement, + ComponentProps["TableHandle"]["Root"] +>((props, ref) => { + const { + className, + children, + draggable, + onDragStart, + onDragEnd, + style, + ...rest + } = props; + + return ( + + ); +}); diff --git a/packages/mantine/src/toolbar/Toolbar.tsx b/packages/mantine/src/toolbar/Toolbar.tsx new file mode 100644 index 0000000000..1ab8f33a64 --- /dev/null +++ b/packages/mantine/src/toolbar/Toolbar.tsx @@ -0,0 +1,23 @@ +import * as Mantine from "@mantine/core"; + +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +type ToolbarProps = ComponentProps["FormattingToolbar"]["Root"] & + ComponentProps["LinkToolbar"]["Root"]; + +export const Toolbar = forwardRef( + (props, ref) => { + const { className, children, onMouseEnter, onMouseLeave } = props; + + return ( + + {children} + + ); + } +); diff --git a/packages/mantine/src/toolbar/ToolbarButton.tsx b/packages/mantine/src/toolbar/ToolbarButton.tsx new file mode 100644 index 0000000000..d6a6ccfe5d --- /dev/null +++ b/packages/mantine/src/toolbar/ToolbarButton.tsx @@ -0,0 +1,97 @@ +import * as Mantine from "@mantine/core"; + +import { isSafari } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; + +export const TooltipContent = (props: { + mainTooltip: string; + secondaryTooltip?: string; +}) => ( + + {props.mainTooltip} + {props.secondaryTooltip && ( + {props.secondaryTooltip} + )} + +); + +type ToolbarButtonProps = ComponentProps["FormattingToolbar"]["Button"] & + ComponentProps["LinkToolbar"]["Button"]; + +/** + * Helper for basic buttons that show in the formatting toolbar. + */ +export const ToolbarButton = forwardRef( + (props, ref) => { + const { + className, + children, + mainTooltip, + secondaryTooltip, + icon, + isSelected, + isDisabled, + onClick, + ...rest + } = props; + + return ( + + }> + {/*Creates an ActionIcon instead of a Button if only an icon is provided as content.*/} + {children ? ( + { + if (isSafari()) { + (e.currentTarget as HTMLButtonElement).focus(); + } + }} + onClick={onClick} + data-selected={isSelected ? "true" : undefined} + data-test={ + mainTooltip.slice(0, 1).toLowerCase() + + mainTooltip.replace(/\s+/g, "").slice(1) + } + size={"xs"} + disabled={isDisabled || false} + ref={ref} + {...rest}> + {children} + + ) : ( + { + if (isSafari()) { + (e.currentTarget as HTMLButtonElement).focus(); + } + }} + onClick={onClick} + data-selected={isSelected ? "true" : undefined} + data-test={ + mainTooltip.slice(0, 1).toLowerCase() + + mainTooltip.replace(/\s+/g, "").slice(1) + } + size={30} + disabled={isDisabled || false} + ref={ref} + {...rest}> + {icon} + + )} + + ); + } +); diff --git a/packages/react/src/mantine/toolbar/ToolbarInputsMenuItem.tsx b/packages/mantine/src/toolbar/ToolbarInputsMenuItem.tsx similarity index 58% rename from packages/react/src/mantine/toolbar/ToolbarInputsMenuItem.tsx rename to packages/mantine/src/toolbar/ToolbarInputsMenuItem.tsx index 16c4b247f6..cfc26e8b41 100644 --- a/packages/react/src/mantine/toolbar/ToolbarInputsMenuItem.tsx +++ b/packages/mantine/src/toolbar/ToolbarInputsMenuItem.tsx @@ -1,17 +1,19 @@ -import { Group, TextInput, TextInputProps } from "@mantine/core"; +import * as Mantine from "@mantine/core"; + import type { IconType } from "react-icons"; +// TODO export type ToolbarInputsMenuItemProps = { icon: IconType; -} & TextInputProps; +} & Mantine.TextInputProps; export const ToolbarInputsMenuItem = (props: ToolbarInputsMenuItemProps) => { const { icon, ...rest } = props; const Icon = props.icon; return ( - - } size={"xs"} {...rest} /> - + + } size={"xs"} {...rest} /> + ); }; diff --git a/packages/mantine/src/toolbar/ToolbarSelect.tsx b/packages/mantine/src/toolbar/ToolbarSelect.tsx new file mode 100644 index 0000000000..7f75969dbd --- /dev/null +++ b/packages/mantine/src/toolbar/ToolbarSelect.tsx @@ -0,0 +1,67 @@ +import * as Mantine from "@mantine/core"; + +import { isSafari } from "@blocknote/core"; +import { ComponentProps } from "@blocknote/react"; +import { forwardRef } from "react"; +import { HiChevronDown } from "react-icons/hi"; + +// TODO: turn into select +export const ToolbarSelect = forwardRef< + HTMLDivElement, + ComponentProps["FormattingToolbar"]["Select"] +>((props, ref) => { + const { className, items, isDisabled } = props; + + const selectedItem = items.filter((p) => p.isSelected)[0]; + + if (!selectedItem) { + return null; + } + + return ( + + + { + if (isSafari()) { + (e.currentTarget as HTMLButtonElement).focus(); + } + }} + leftSection={selectedItem.icon} + rightSection={} + size={"xs"} + variant={"subtle"} + disabled={isDisabled}> + {selectedItem.text} + + + + {items.map((item) => ( + + ) : ( + // Ensures space for tick even if item isn't currently selected. +
+ ) + } + disabled={item.isDisabled}> + {item.text} + + ))} + + + ); +}); diff --git a/packages/mantine/tsconfig.json b/packages/mantine/tsconfig.json new file mode 100644 index 0000000000..607ad93cfa --- /dev/null +++ b/packages/mantine/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "Node", + "jsx": "react-jsx", + "strict": true, + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "noEmit": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "outDir": "dist", + "declaration": true, + "declarationDir": "types", + "composite": true, + "skipLibCheck": true, + }, + "include": ["src"], + "references": [ + { + "path": "../core" + }, + { + "path": "../react" + } + ] +} diff --git a/packages/mantine/vite.config.ts b/packages/mantine/vite.config.ts new file mode 100644 index 0000000000..0e9e1ed2f5 --- /dev/null +++ b/packages/mantine/vite.config.ts @@ -0,0 +1,52 @@ +import react from "@vitejs/plugin-react"; +import * as path from "path"; +import { webpackStats } from "rollup-plugin-webpack-stats"; +import { defineConfig } from "vite"; +import pkg from "./package.json"; +// import eslintPlugin from "vite-plugin-eslint"; + +// https://vitejs.dev/config/ +export default defineConfig((conf) => ({ + test: { + environment: "jsdom", + setupFiles: ["./vitestSetup.ts"], + }, + plugins: [react(), webpackStats()], + // used so that vitest resolves the core package from the sources instead of the built version + resolve: { + alias: + conf.command === "build" + ? ({} as Record) + : ({ + // load live from sources with live reload working + "@blocknote/core": path.resolve(__dirname, "../core/src/"), + "@blocknote/react": path.resolve(__dirname, "../react/src/"), + } as Record), + }, + build: { + sourcemap: true, + lib: { + entry: path.resolve(__dirname, "src/index.tsx"), + name: "blocknote-mantine", + fileName: "blocknote-mantine", + }, + rollupOptions: { + // make sure to externalize deps that shouldn't be bundled + // into your library + external: Object.keys({ + ...pkg.dependencies, + ...pkg.peerDependencies, + ...pkg.devDependencies, + }), + output: { + // Provide global variables to use in the UMD build + // for externalized deps + globals: { + react: "React", + "react-dom": "ReactDOM", + }, + interop: "compat", // https://rollupjs.org/migration/#changed-defaults + }, + }, + }, +})); diff --git a/packages/react/package.json b/packages/react/package.json index e09bd6dfc8..33a1829a6c 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -50,12 +50,8 @@ "clean": "rimraf dist && rimraf types" }, "dependencies": { - "@ariakit/react": "^0.4.3", "@blocknote/core": "^0.12.1", "@floating-ui/react": "^0.26.4", - "@mantine/core": "^7.5.0", - "@mantine/hooks": "^7.5.0", - "@mantine/utils": "^6.0.21", "@tiptap/core": "^2.0.3", "@tiptap/react": "^2.0.3", "lodash.merge": "^4.6.2", diff --git a/packages/react/src/ariakit/ariakit.css b/packages/react/src/ariakit/ariakit.css deleted file mode 100644 index 61493d7e06..0000000000 --- a/packages/react/src/ariakit/ariakit.css +++ /dev/null @@ -1,399 +0,0 @@ -.button { - display: flex; - height: 2.5rem; - user-select: none; - align-items: center; - white-space: nowrap; - border-style: none; - background-color: hsl(204 20% 100%); - padding-left: 1rem; - padding-right: 1rem; - font-size: 1rem; - line-height: 1.5rem; - color: hsl(204 4% 0%); - text-decoration-line: none; - outline-width: 2px; - outline-offset: 2px; - outline-color: hsl(204 100% 40%); - --border: rgba(0, 0, 0, 0.1); - --highlight: rgba(255, 255, 255, 0.2); - --shadow: rgba(0, 0, 0, 0.1); - box-shadow: inset 0 0 0 1px var(--border), inset 0 2px 0 var(--highlight), - inset 0 -1px 0 var(--shadow), 0 1px 1px var(--shadow); - scroll-margin-left: 0.25rem; - scroll-margin-right: 0.25rem; - gap: 0.5rem; - border-radius: 0.25rem; - justify-content: space-between; - width: auto; -} - -.button:hover { - background-color: hsl(204 20% 96%); -} - -.button[aria-disabled="true"] { - opacity: 0.5; -} - -.button[aria-expanded="true"] { - background-color: hsl(204 20% 96%); -} - -.button[data-focus-visible] { - outline-style: solid; -} - -.button:active, -.button[data-active] { - padding-top: 0.125rem; - box-shadow: inset 0 0 0 1px var(--border), inset 0 2px 0 var(--border); -} - -:is(.dark .button) { - background-color: hsl(204 20% 100% / 0.05); - color: hsl(204 20% 100%); - --shadow: rgba(0, 0, 0, 0.25); - --border: rgba(255, 255, 255, 0.1); - --highlight: rgba(255, 255, 255, 0.05); - box-shadow: inset 0 0 0 1px var(--border), inset 0 -1px 0 1px var(--shadow), - inset 0 1px 0 var(--highlight); -} - -:is(.dark .button:hover) { - background-color: hsl(204 20% 100% / 0.1); -} - -:is(.dark .button)[aria-expanded="true"] { - background-color: hsl(204 20% 100% / 0.1); -} - -:is(.dark .button:active), -:is(.dark .button[data-active]) { - box-shadow: inset 0 0 0 1px var(--border), inset 0 1px 1px 1px var(--shadow); -} - -@media (min-width: 640px) { - .button { - gap: 0.5rem; - } -} - -.secondary { - background-color: transparent; - color: currentColor; - box-shadow: none; -} - -.secondary:hover { - background-color: hsl(204 4% 0% / 0.05); -} - -:is(.dark .secondary) { - background-color: transparent; - box-shadow: none; -} - -:is(.dark .secondary:hover) { - background-color: hsl(204 20% 100% / 0.05); -} - -:is(.dark .secondary:active), -:is(.dark .secondary[data-active]) { - box-shadow: none; -} - -.bn-toolbar { - display: flex; - max-width: 100%; - align-items: center; - gap: 0.25rem; - overflow-x: auto; - border-radius: 0.5rem; - background-color: hsl(204 20% 100%); - padding: 0.25rem; - box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); -} - -:is(.dark .bn-toolbar) { - background-color: hsl(204 4% 16%); - box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.25), 0 1px 2px -1px rgb(0 0 0 / 0.1); -} - -.separator { - height: 2rem; - border-right-width: 1px; - border-color: hsl(204 20% 88%); -} - -:is(.dark .separator) { - border-color: hsl(204 4% 28%); -} - -.popover { - z-index: 50; - display: flex; - max-height: min(var(--popover-available-height, 300px), 300px); - flex-direction: column; - overflow: auto; - overscroll-behavior: contain; - border-radius: 0.5rem; - border-width: 1px; - border-style: solid; - border-color: hsl(204 20% 88%); - background-color: hsl(204 20% 100%); - padding: 0.5rem; - color: hsl(204 4% 0%); - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); -} - -.popover:focus-visible, -.popover[data-focus-visible] { - outline: 2px solid hsl(204 100% 40%); - outline-offset: -1px; -} - -:is(.dark .popover) { - border-color: hsl(204 4% 24%); - background-color: hsl(204 4% 16%); - color: hsl(204 20% 100%); - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.25), - 0 4px 6px -4px rgb(0 0 0 / 0.1); -} - -.select-item { - display: flex; - cursor: default; - scroll-margin: 0.5rem; - align-items: center; - gap: 0.5rem; - border-radius: 0.25rem; - padding: 0.5rem; - outline: none !important; - padding-right: 2rem; -} - -.select-item[aria-disabled="true"] { - opacity: 0.5; -} - -.select-item[data-active-item] { - background-color: hsl(204 100% 40%); - color: hsl(204 20% 100%); -} - -.input { - height: 2.5rem; - width: 100%; - border-radius: 0.375rem; - border-style: none; - background-color: hsl(204 20% 94% / 0.4); - padding-left: 1rem; - padding-right: 1rem; - font-size: 1rem; - line-height: 1.5rem; - color: hsl(204 4% 0%); - box-shadow: - inset 0 0 0 1px rgba(0 0 0 / 0.1), - inset 0 2px 5px 0 rgba(0 0 0 / 0.05); -} - -.input::placeholder { - color: hsl(204 4% 0% / 0.6); -} - -.input:hover { - background-color: hsl(204 20% 94%); -} - -.input:focus-visible, -.input[data-focus-visible] { - outline: 2px solid hsl(204 100% 40%); - outline-offset: -1px; -} - -:is(.dark .input) { - background-color: hsl(204 4% 10%); - color: hsl(204 20% 100%); - box-shadow: - inset 0 0 0 1px rgba(255 255 255 / 0.12), - inset 0 -1px 0 0 rgba(255 255 255 / 0.05), - inset 0 2px 5px 0 rgba(0 0 0 / 0.15); -} - -:is(.dark .input)::placeholder { - color: hsl(204 20% 100% / 46%); -} - -:is(.dark .input:hover) { - background-color: hsl(204 4% 8%); -} - -:is(.dark .bn-image-panel) { - background-color: hsl(204 4% 16%); - box-shadow: - 0 1px 3px 0 rgb(0 0 0 / 0.25), - 0 1px 2px -1px rgb(0 0 0 / 0.1); -} - -.tab-list { - display: flex; - gap: 0.5rem; -} - -.tab { - display: flex; - height: 2.5rem; - user-select: none; - align-items: center; - justify-content: center; - gap: 0.5rem; - white-space: nowrap; - border-radius: 0.25rem; - border-style: none; - padding-left: 1rem; - padding-right: 1rem; - font-size: 1rem; - line-height: 1.5rem; - text-decoration-line: none; - outline-width: 2px; - outline-offset: 2px; - outline-color: hsl(204 100% 40%); -} - -.tab:hover { - background-color: hsl(204 4% 0% / 7.5%); -} - -.tab[aria-disabled="true"] { - opacity: 0.5; -} - -.tab[aria-selected="true"] { - background-color: hsl(204 100% 40%); - color: hsl(204 20% 100%); -} - -.tab:hover[aria-selected="true"] { - background-color: hsl(204 100% 32%); -} - -.tab[data-focus-visible] { - outline-style: solid; -} - -.tab:active, -.tab[data-active] { - padding-top: 0.125rem; -} - -:is(.dark .tab:hover) { - background-color: hsl(204 20% 100% / 0.1); -} - -:is(.dark .tab[aria-selected="true"]) { - background-color: hsl(204 100% 40%); - color: hsl(204 20% 100%); -} - -:is(.dark .tab:hover[aria-selected="true"]) { - background-color: hsl(204 100% 32%); -} - -.panel { - padding: 0.5rem; -} - -.bn-menu { - position: relative; - z-index: 50; - display: flex; - max-height: var(--popover-available-height); - min-width: 180px; - flex-direction: column; - overscroll-behavior: contain; - border-radius: 0.5rem; - border-width: 1px; - border-style: solid; - border-color: hsl(204 20% 88%); - background-color: hsl(204 20% 100%); - padding: 0.5rem; - color: hsl(204 4% 0%); - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - outline: none !important; - overflow: visible; -} - -:is(.dark .bn-menu) { - border-color: hsl(204 4% 24%); - background-color: hsl(204 4% 16%); - color: hsl(204 20% 100%); - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.25), - 0 4px 6px -4px rgb(0 0 0 / 0.1); -} - -.bn-menu-item { - display: flex; - cursor: default; - scroll-margin: 0.5rem; - align-items: center; - gap: 0.5rem; - border-radius: 0.25rem; - padding: 0.5rem; - outline: none !important; -} - -.bn-menu-item[aria-disabled="true"] { - opacity: 0.25; -} - -.bn-menu-item[data-active-item] { - background-color: hsl(204 100% 40%); - color: hsl(204 20% 100%); -} - -.bn-menu-item:active, -.bn-menu-item[data-active] { - background-color: hsl(204 100% 32%); - padding-top: 9px; - padding-bottom: 7px; -} - -.bn-menu:not(:focus) .bn-menu-item:not(:focus)[aria-expanded="true"] { - background-color: hsl(204 4% 0% / 7.5%); - color: currentColor; -} - -:is( - .dark .bn-menu:not(:focus) .bn-menu-item:not(:focus)[aria-expanded="true"] - ) { - background-color: hsl(204 20% 100% / 0.1); -} - -.bn-menu-item .label { - flex: 1 1 0%; -} - -.bn-menu-label { - cursor: default; - padding: 0.5rem; - padding-left: 0.75rem; - padding-right: 0.75rem; - font-size: 0.875rem; - line-height: 1.25rem; - font-weight: 500; - opacity: 0.5; -} - -.bn-image-panel { - display: flex; - flex-direction: column; - gap: 0.5rem; - border-radius: 0.5rem; - background-color: hsl(204 20% 100%); - padding: 0.5rem; - box-shadow: - 0 1px 3px 0 rgb(0 0 0 / 0.1), - 0 1px 2px -1px rgb(0 0 0 / 0.1); -} - diff --git a/packages/react/src/ariakit/components.tsx b/packages/react/src/ariakit/components.tsx deleted file mode 100644 index 634cc6ed5a..0000000000 --- a/packages/react/src/ariakit/components.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { ComponentsContextValue } from "../editor/ComponentsContext"; -import "./ariakit.css"; -import { Form } from "./input/Form"; -import { TextInput } from "./input/TextInput"; -import { - Menu, - MenuDivider, - MenuDropdown, - MenuItem, - MenuLabel, - MenuTrigger, -} from "./menu/Menu"; -import { Popover, PopoverContent, PopoverTrigger } from "./popover/Popover"; -import { Toolbar } from "./toolbar/Toolbar"; -import { ToolbarButton } from "./toolbar/ToolbarButton"; -import { ToolbarSelect } from "./toolbar/ToolbarSelect"; - -import { Panel } from "./panel/Panel"; -import { PanelButton } from "./panel/PanelButton"; -import { PanelFileInput } from "./panel/PanelFileInput"; -import { PanelTab } from "./panel/PanelTab"; -import { PanelTextInput } from "./panel/PanelTextInput"; - -export const ariakitComponents: ComponentsContextValue = { - Form, - TextInput, - Toolbar: Toolbar, - ToolbarSelect, - ToolbarButton, - Menu, - MenuTrigger, - MenuDropdown, - MenuDivider, - MenuLabel, - MenuItem, - Panel, - PanelButton, - PanelFileInput, - PanelTab, - PanelTextInput, - Popover, - PopoverContent, - PopoverTrigger, -}; diff --git a/packages/react/src/ariakit/input/Form.tsx b/packages/react/src/ariakit/input/Form.tsx deleted file mode 100644 index bd7770164a..0000000000 --- a/packages/react/src/ariakit/input/Form.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import * as Ariakit from "@ariakit/react"; - -export const Form = (props: { children: React.ReactNode }) => { - const { ...rest } = props; - - return ; -}; diff --git a/packages/react/src/ariakit/input/TextInput.tsx b/packages/react/src/ariakit/input/TextInput.tsx deleted file mode 100644 index cade54c139..0000000000 --- a/packages/react/src/ariakit/input/TextInput.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as Ariakit from "@ariakit/react"; -import { TextInputProps } from "../../editor/ComponentsContext"; - -export const TextInput = (props: TextInputProps) => { - const { icon, ...rest } = props; - - // TODO: support icon - return ( - <> - {props.label && ( - {props.label} - )} - - - ); -}; diff --git a/packages/react/src/ariakit/menu/Menu.tsx b/packages/react/src/ariakit/menu/Menu.tsx deleted file mode 100644 index 7050aef418..0000000000 --- a/packages/react/src/ariakit/menu/Menu.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import * as Ariakit from "@ariakit/react"; -import { mergeCSSClasses } from "@blocknote/core"; -import { HTMLAttributes, forwardRef } from "react"; -import { MenuItemProps, MenuProps } from "../../editor/ComponentsContext"; -export { MenuSeparator as MenuDivider } from "@ariakit/react"; - -export const Menu = (props: MenuProps) => { - const { onOpenChange, position, ...rest } = props; - - return ( - - ); -}; - -export const MenuDropdown = forwardRef< - HTMLDivElement, - HTMLAttributes ->((props, ref) => { - const { className, children, ...rest } = props; - - return ( - - {children} - - ); -}); - -export const MenuItem = forwardRef( - (props, ref) => { - const { className, children, icon, checked, expandArrow, ...rest } = props; - - if (expandArrow) { - return ( - - {icon} - {children} - - {checked !== undefined && } - - ); - } - return ( - - {icon} - {children} - {checked !== undefined && } - - ); - } -); - -export const MenuLabel = forwardRef< - HTMLDivElement, - HTMLAttributes ->((props, ref) => { - const { className, children, ...rest } = props; - - return ( - - {children} - - ); -}); - -export const MenuTrigger = forwardRef< - HTMLDivElement, - HTMLAttributes ->((props, ref) => { - const { className, children, ...rest } = props; - - return ( - - ); -}); diff --git a/packages/react/src/ariakit/panel/Panel.tsx b/packages/react/src/ariakit/panel/Panel.tsx deleted file mode 100644 index ded7c08241..0000000000 --- a/packages/react/src/ariakit/panel/Panel.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as Ariakit from "@ariakit/react"; - -import { PanelProps } from "../../editor/ComponentsContext"; - -export const Panel = (props: PanelProps) => { - return ( -
- { - if (activeId) { - props.setOpenTab(activeId); - } - }}> - {/*{props.loading && }*/} - - - {props.tabs.map((tab) => ( - - {tab.name} - - ))} - - - {props.tabs.map((tab) => ( - - {tab.tabPanel} - - ))} - -
- ); -}; diff --git a/packages/react/src/ariakit/panel/PanelButton.tsx b/packages/react/src/ariakit/panel/PanelButton.tsx deleted file mode 100644 index 9c6a6345bc..0000000000 --- a/packages/react/src/ariakit/panel/PanelButton.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as Ariakit from "@ariakit/react"; - -import { PanelButtonProps } from "../../editor/ComponentsContext"; -import { mergeCSSClasses } from "@blocknote/core"; - -export const PanelButton = (props: PanelButtonProps) => { - const { children, className, ...rest } = props; - - return ( - - {children} - - ); -}; diff --git a/packages/react/src/ariakit/panel/PanelFileInput.tsx b/packages/react/src/ariakit/panel/PanelFileInput.tsx deleted file mode 100644 index 96d03c01f7..0000000000 --- a/packages/react/src/ariakit/panel/PanelFileInput.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as Ariakit from "@ariakit/react"; - -import { PanelFileInputProps } from "../../editor/ComponentsContext"; - -export const PanelFileInput = (props: PanelFileInputProps) => ( - - props.onChange?.(e.target.files![0])} - placeholder={props.placeholder} - /> - -); diff --git a/packages/react/src/ariakit/panel/PanelTab.tsx b/packages/react/src/ariakit/panel/PanelTab.tsx deleted file mode 100644 index dfb92e3fa9..0000000000 --- a/packages/react/src/ariakit/panel/PanelTab.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { mergeCSSClasses } from "@blocknote/core"; - -import { PanelTabProps } from "../../editor/ComponentsContext"; - -export const PanelTab = (props: PanelTabProps) => { - const { className, children, ...rest } = props; - - return ( -
- {children} -
- ); -}; diff --git a/packages/react/src/ariakit/panel/PanelTextInput.tsx b/packages/react/src/ariakit/panel/PanelTextInput.tsx deleted file mode 100644 index 3a63326490..0000000000 --- a/packages/react/src/ariakit/panel/PanelTextInput.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import * as Ariakit from "@ariakit/react"; - -import { PanelTextInputProps } from "../../editor/ComponentsContext"; - -export const PanelTextInput = (props: PanelTextInputProps) => { - const { children, ...rest } = props; - - return ( - - - - ); -}; diff --git a/packages/react/src/ariakit/popover/Popover.tsx b/packages/react/src/ariakit/popover/Popover.tsx deleted file mode 100644 index 3e9b3a7390..0000000000 --- a/packages/react/src/ariakit/popover/Popover.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as Ariakit from "@ariakit/react"; -import { mergeCSSClasses } from "@blocknote/core"; -import { forwardRef, HTMLAttributes } from "react"; -export { - PopoverProvider as Popover, - Popover as PopoverContent, -} from "@ariakit/react"; - -export const PopoverTrigger = forwardRef< - HTMLButtonElement, - HTMLAttributes ->((props, ref) => { - const { className, children, ...rest } = props; - - return ( - - ); -}); diff --git a/packages/react/src/ariakit/toolbar/Toolbar.tsx b/packages/react/src/ariakit/toolbar/Toolbar.tsx deleted file mode 100644 index 15f2fed7c5..0000000000 --- a/packages/react/src/ariakit/toolbar/Toolbar.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as Ariakit from "@ariakit/react"; -import { mergeCSSClasses } from "@blocknote/core"; -import { forwardRef, HTMLAttributes } from "react"; - -export const Toolbar = forwardRef< - HTMLDivElement, - HTMLAttributes ->((props, ref) => { - const { className, children, ...rest } = props; - - return ( - - {children} - - ); -}); - -// export const ToolbarButton = forwardRef( -// diff --git a/packages/react/src/ariakit/toolbar/ToolbarButton.tsx b/packages/react/src/ariakit/toolbar/ToolbarButton.tsx deleted file mode 100644 index 4d36fa80c8..0000000000 --- a/packages/react/src/ariakit/toolbar/ToolbarButton.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import * as Ariakit from "@ariakit/react"; -import { isSafari } from "@blocknote/core"; -import { forwardRef } from "react"; -import { ToolbarButtonProps } from "../../editor/ComponentsContext"; - -/** - * Helper for basic buttons that show in the formatting toolbar. - */ -// TODO: implement tooltip -export const ToolbarButton = forwardRef( - (props, ref) => { - return ( - { - if (isSafari()) { - (e.currentTarget as HTMLButtonElement).focus(); - } - }} - onClick={props.onClick} - data-selected={props.isSelected ? "true" : undefined} - data-test={ - props.mainTooltip.slice(0, 1).toLowerCase() + - props.mainTooltip.replace(/\s+/g, "").slice(1) - } - // size={"xs"} - disabled={props.isDisabled || false} - ref={ref}> - {props.icon} - {props.children} - - ); - - return ( - - { - if (isSafari()) { - (e.currentTarget as HTMLButtonElement).focus(); - } - }} - onClick={props.onClick} - data-selected={props.isSelected ? "true" : undefined} - data-test={ - props.mainTooltip.slice(0, 1).toLowerCase() + - props.mainTooltip.replace(/\s+/g, "").slice(1) - } - // size={"xs"} - disabled={props.isDisabled || false} - ref={ref}> - }> - {props.icon} - {props.children} - - -
{props.mainTooltip}
- {props.secondaryTooltip &&
{props.secondaryTooltip}
} -
-
- ); - } -); diff --git a/packages/react/src/ariakit/toolbar/ToolbarSelect.tsx b/packages/react/src/ariakit/toolbar/ToolbarSelect.tsx deleted file mode 100644 index e0b4a7065b..0000000000 --- a/packages/react/src/ariakit/toolbar/ToolbarSelect.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as Ariakit from "@ariakit/react"; -import { ToolbarSelectProps } from "../../mantine/toolbar/ToolbarSelect"; - -export function ToolbarSelect(props: ToolbarSelectProps) { - const selectedItem = props.items.filter((p) => p.isSelected)[0]; - - const setValue = (value: string) => { - props.items.find((item) => item.text === value)!.onClick?.(); - }; - - return ( - - }> - {selectedItem.icon && } {selectedItem.text}{" "} - - - - {props.items.map((option) => ( - - {option.icon && } {option.text} - - ))} - - - ); -} diff --git a/packages/react/src/components/ColorPicker/ColorPicker.tsx b/packages/react/src/components/ColorPicker/ColorPicker.tsx index e60617f3e7..5c73c1f4ce 100644 --- a/packages/react/src/components/ColorPicker/ColorPicker.tsx +++ b/packages/react/src/components/ColorPicker/ColorPicker.tsx @@ -1,6 +1,20 @@ import { useComponentsContext } from "../../editor/ComponentsContext"; +import { useDictionaryContext } from "../../i18n/dictionary"; import { ColorIcon } from "./ColorIcon"; +const colors = [ + "default", + "gray", + "brown", + "red", + "orange", + "yellow", + "green", + "blue", + "purple", + "pink", +] as const; + export const ColorPicker = (props: { onClick?: () => void; iconSize?: number; @@ -13,25 +27,16 @@ export const ColorPicker = (props: { setColor: (color: string) => void; }; }) => { - const components = useComponentsContext()!; - + const Components = useComponentsContext()!; + const dict = useDictionaryContext(); const TextColorSection = () => props.text ? ( <> - Text - {[ - "default", - "gray", - "brown", - "red", - "orange", - "yellow", - "green", - "blue", - "purple", - "pink", - ].map((color) => ( - + {dict.color_picker.text_title} + + {colors.map((color) => ( + { props.onClick && props.onClick(); props.text!.setColor(color); @@ -40,8 +45,8 @@ export const ColorPicker = (props: { icon={} checked={props.text!.color === color} key={"text-color-" + color}> - {color.charAt(0).toUpperCase() + color.slice(1)} - + {dict.color_picker.colors[color]} + ))} ) : null; @@ -49,20 +54,11 @@ export const ColorPicker = (props: { const BackgroundColorSection = () => props.background ? ( <> - Background - {[ - "default", - "gray", - "brown", - "red", - "orange", - "yellow", - "green", - "blue", - "purple", - "pink", - ].map((color) => ( - + {dict.color_picker.background_title} + + {colors.map((color) => ( + { props.onClick && props.onClick(); props.background!.setColor(color); @@ -71,8 +67,8 @@ export const ColorPicker = (props: { icon={} key={"background-color-" + color} checked={props.background!.color === color}> - {color.charAt(0).toUpperCase() + color.slice(1)} - + {dict.color_picker.colors[color]} + ))} ) : null; diff --git a/packages/react/src/components/FormattingToolbar/DefaultButtons/BasicTextStyleButton.tsx b/packages/react/src/components/FormattingToolbar/DefaultButtons/BasicTextStyleButton.tsx index eccc62fec7..f4194be708 100644 --- a/packages/react/src/components/FormattingToolbar/DefaultButtons/BasicTextStyleButton.tsx +++ b/packages/react/src/components/FormattingToolbar/DefaultButtons/BasicTextStyleButton.tsx @@ -19,6 +19,7 @@ import { useComponentsContext } from "../../../editor/ComponentsContext"; import { useBlockNoteEditor } from "../../../hooks/useBlockNoteEditor"; import { useEditorContentOrSelectionChange } from "../../../hooks/useEditorContentOrSelectionChange"; import { useSelectedBlocks } from "../../../hooks/useSelectedBlocks"; +import { useDictionaryContext } from "../../../i18n/dictionary"; type BasicTextStyle = "bold" | "italic" | "underline" | "strike" | "code"; @@ -30,14 +31,6 @@ const icons = { code: RiCodeFill, } satisfies Record; -const shortcuts = { - bold: "Mod+B", - italic: "Mod+I", - underline: "Mod+U", - strike: "Mod+Shift+X", - code: "", -} satisfies Record; - function checkBasicTextStyleInSchema