@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.
@@ -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.0",
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/eslint-config": "0.0.0",
76
- "@qkix/tsconfig": "0.0.0"
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-plugin-better-blocks.git",
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-plugin-better-blocks/issues"
107
+ "url": "https://github.com/qkix/strapi-plugins/issues"
107
108
  },
108
- "homepage": "https://github.com/qkix/strapi-plugin-better-blocks#readme",
109
+ "homepage": "https://github.com/qkix/strapi-plugins#readme",
109
110
  "nx": {
110
111
  "tags": [
111
112
  "scope:plugin"