@qkix/strapi-plugin-better-blocks 0.23.0 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -10
- package/dist/admin/index.js +220 -220
- package/dist/admin/index.mjs +3999 -3905
- package/dist/admin/src/blockRegistry.d.ts +87 -0
- package/dist/admin/src/components/BlocksInput/BlocksEditor.d.ts +8 -0
- package/dist/admin/src/index.d.ts +7 -0
- package/package.json +8 -7
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How another Strapi plugin adds a block type to the Better Blocks editor.
|
|
3
|
+
*
|
|
4
|
+
* Unlike the renderers, which take their registrations as a prop, the editor
|
|
5
|
+
* keeps a module-level registry. That is not an oversight: the Strapi admin is
|
|
6
|
+
* a single browser application whose plugins register once at boot, exactly
|
|
7
|
+
* like `app.customFields.register`. There is no second document being edited in
|
|
8
|
+
* another request to leak into.
|
|
9
|
+
*
|
|
10
|
+
* Registering is the *only* supported way in. Adding a block by editing this
|
|
11
|
+
* package is how the editor, both renderers and the validator ended up with
|
|
12
|
+
* four separate hardcoded lists of block types in the first place.
|
|
13
|
+
*/
|
|
14
|
+
/// <reference types="react" />
|
|
15
|
+
import type { BlockDefinition } from '@qkix/better-blocks-core';
|
|
16
|
+
import type { Editor } from 'slate';
|
|
17
|
+
import type { MessageDescriptor } from 'react-intl';
|
|
18
|
+
import type { RenderElementProps } from 'slate-react';
|
|
19
|
+
import type { CSSProperties } from 'styled-components';
|
|
20
|
+
/**
|
|
21
|
+
* A block type contributed by another package.
|
|
22
|
+
*
|
|
23
|
+
* Extends the core {@link BlockDefinition}, so a package writes `type` and
|
|
24
|
+
* `content` once and the same object teaches the validator, the migrator and
|
|
25
|
+
* both renderers about the block.
|
|
26
|
+
*/
|
|
27
|
+
export type EditorBlockDefinition = BlockDefinition & {
|
|
28
|
+
/** Draws the block inside the editor. Slate calls this with its element props. */
|
|
29
|
+
renderElement: (props: RenderElementProps) => React.JSX.Element;
|
|
30
|
+
/**
|
|
31
|
+
* Icon for the Insert menu and the slash command. Required to appear in
|
|
32
|
+
* either — a block with no icon is still rendered, just not offered.
|
|
33
|
+
*/
|
|
34
|
+
icon?: React.ComponentType;
|
|
35
|
+
/** Menu label. A plain string is fine; a descriptor gets translated. */
|
|
36
|
+
label?: MessageDescriptor | string;
|
|
37
|
+
/**
|
|
38
|
+
* Inserts an empty block of this type at the selection. Required for the
|
|
39
|
+
* block to appear in the Insert menu or the slash command, since without it
|
|
40
|
+
* there is nothing for those to do.
|
|
41
|
+
*/
|
|
42
|
+
insert?: (editor: Editor) => void;
|
|
43
|
+
/** Text that converts into this block as you type, e.g. '```mermaid'. */
|
|
44
|
+
snippets?: string[];
|
|
45
|
+
/**
|
|
46
|
+
* Anything `isVoid` cannot express — custom normalization, paste handling,
|
|
47
|
+
* key bindings. Applied when the editor is created.
|
|
48
|
+
*/
|
|
49
|
+
withEditor?: (editor: Editor) => Editor;
|
|
50
|
+
/** Nudges the drag handle down, for blocks whose first line is not text. */
|
|
51
|
+
dragHandleTopMargin?: CSSProperties['marginTop'];
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Adds a block type to the editor. Call from a Strapi plugin's `register()`.
|
|
55
|
+
*
|
|
56
|
+
* Throws on the two mistakes that would otherwise surface much later as a block
|
|
57
|
+
* that mysteriously does not appear: shadowing a built-in type, and registering
|
|
58
|
+
* the same type twice.
|
|
59
|
+
*/
|
|
60
|
+
export declare function registerBlock(definition: EditorBlockDefinition): void;
|
|
61
|
+
/** Every registered block, in registration order. */
|
|
62
|
+
export declare function getRegisteredBlocks(): EditorBlockDefinition[];
|
|
63
|
+
/**
|
|
64
|
+
* Whether the block can be offered in the Insert menu and the slash command.
|
|
65
|
+
*
|
|
66
|
+
* All three are needed: something to draw, something to name it, and something
|
|
67
|
+
* to do when it is picked. A block missing any of them still renders in a
|
|
68
|
+
* document, it just is not offered as a thing to add.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isOfferedInMenus(definition: EditorBlockDefinition): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The block's menu label as react-intl wants it. A plain string becomes the
|
|
73
|
+
* default message under a generated id, so it shows as written until someone
|
|
74
|
+
* ships a translation for it.
|
|
75
|
+
*/
|
|
76
|
+
export declare function blockLabelDescriptor(definition: EditorBlockDefinition): MessageDescriptor;
|
|
77
|
+
/** Empties the registry. Exists for tests; the admin never needs it. */
|
|
78
|
+
export declare function clearRegisteredBlocks(): void;
|
|
79
|
+
/**
|
|
80
|
+
* Teaches Slate about the registered blocks.
|
|
81
|
+
*
|
|
82
|
+
* Void-ness is derived from the declared content model rather than asked for
|
|
83
|
+
* separately: a block that renders from its own attributes is exactly a Slate
|
|
84
|
+
* void, and getting that wrong is the difference between a working block and an
|
|
85
|
+
* uneditable one.
|
|
86
|
+
*/
|
|
87
|
+
export declare function withRegisteredBlocks(editor: Editor): Editor;
|
|
@@ -29,10 +29,18 @@ type NonSelectorBlockKey = 'list-item' | 'link' | 'horizontal-line' | 'table' |
|
|
|
29
29
|
declare const selectorBlockKeys: readonly ["paragraph", "heading-one", "heading-two", "heading-three", "heading-four", "heading-five", "heading-six", "list-ordered", "list-unordered", "list-todo", "image", "audio", "video", "embed", "quote", "code", "math", "diagram", "callout", "details", "button", "social-embed"];
|
|
30
30
|
type SelectorBlockKey = (typeof selectorBlockKeys)[number];
|
|
31
31
|
declare const isSelectorBlockKey: (key: unknown) => key is "image" | "audio" | "math" | "diagram" | "callout" | "details" | "button" | "social-embed" | "embed" | "video" | "code" | "paragraph" | "heading-one" | "heading-two" | "heading-three" | "heading-four" | "heading-five" | "heading-six" | "list-ordered" | "list-unordered" | "list-todo" | "quote";
|
|
32
|
+
/**
|
|
33
|
+
* The built-in keys are spelled out so `blocks.paragraph` stays typed, while
|
|
34
|
+
* the index signature leaves room for the types other packages register — see
|
|
35
|
+
* `registerBlock`. Without it, every consumer that walks the store would have
|
|
36
|
+
* to widen at the call site.
|
|
37
|
+
*/
|
|
32
38
|
type BlocksStore = {
|
|
33
39
|
[K in SelectorBlockKey]: SelectorBlock;
|
|
34
40
|
} & {
|
|
35
41
|
[K in NonSelectorBlockKey]: NonSelectorBlock;
|
|
42
|
+
} & {
|
|
43
|
+
[key: string]: SelectorBlock | NonSelectorBlock;
|
|
36
44
|
};
|
|
37
45
|
interface BlocksEditorContextValue {
|
|
38
46
|
blocks: BlocksStore;
|
|
@@ -8,3 +8,10 @@ declare const _default: {
|
|
|
8
8
|
}[]>;
|
|
9
9
|
};
|
|
10
10
|
export default _default;
|
|
11
|
+
/**
|
|
12
|
+
* The extension surface. Another Strapi plugin adds a block type by calling
|
|
13
|
+
* `registerBlock` from its own `register()`, which runs before any editor is
|
|
14
|
+
* mounted.
|
|
15
|
+
*/
|
|
16
|
+
export { registerBlock, getRegisteredBlocks, clearRegisteredBlocks, } from './blockRegistry';
|
|
17
|
+
export type { EditorBlockDefinition } from './blockRegistry';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qkix/strapi-plugin-better-blocks",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"description": "An enhanced Rich Text (Blocks) field for Strapi with inline color picker and more",
|
|
5
5
|
"strapi": {
|
|
6
6
|
"kind": "plugin",
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"remark-math": "^6.0.0",
|
|
55
55
|
"remark-parse": "^11.0.0",
|
|
56
56
|
"shiki": "^4.3.0",
|
|
57
|
-
"unified": "^11.0.5"
|
|
57
|
+
"unified": "^11.0.5",
|
|
58
|
+
"@qkix/better-blocks-core": "^0.2.1"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@strapi/sdk-plugin": "^5.3.2",
|
|
@@ -72,8 +73,8 @@
|
|
|
72
73
|
"styled-components": "^6.1.17",
|
|
73
74
|
"typescript": "^5.8.3",
|
|
74
75
|
"vitest": "^3.2.4",
|
|
75
|
-
"@qkix/
|
|
76
|
-
"@qkix/
|
|
76
|
+
"@qkix/tsconfig": "0.0.0",
|
|
77
|
+
"@qkix/eslint-config": "0.0.0"
|
|
77
78
|
},
|
|
78
79
|
"peerDependencies": {
|
|
79
80
|
"@radix-ui/react-toolbar": "^1.0.0",
|
|
@@ -99,13 +100,13 @@
|
|
|
99
100
|
"author": "qkix",
|
|
100
101
|
"repository": {
|
|
101
102
|
"type": "git",
|
|
102
|
-
"url": "git+https://github.com/qkix/strapi-
|
|
103
|
+
"url": "git+https://github.com/qkix/strapi-plugins.git",
|
|
103
104
|
"directory": "packages/strapi-plugin-better-blocks"
|
|
104
105
|
},
|
|
105
106
|
"bugs": {
|
|
106
|
-
"url": "https://github.com/qkix/strapi-
|
|
107
|
+
"url": "https://github.com/qkix/strapi-plugins/issues"
|
|
107
108
|
},
|
|
108
|
-
"homepage": "https://github.com/qkix/strapi-
|
|
109
|
+
"homepage": "https://github.com/qkix/strapi-plugins#readme",
|
|
109
110
|
"nx": {
|
|
110
111
|
"tags": [
|
|
111
112
|
"scope:plugin"
|