@plaudit/gutenberg-api-extensions 2.91.1 → 2.92.0
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/CHANGELOG.md +5 -0
- package/dist/editor/insert-sibling-or-child-block-shortcut.d.ts +12 -0
- package/dist/editor/insert-sibling-or-child-block-shortcut.js +42 -0
- package/dist/editor/insert-sibling-or-child-block-shortcut.js.map +1 -0
- package/dist/editor/install-insert-sole-allowed-block-shortcut-support.d.ts +1 -0
- package/dist/editor/install-insert-sole-allowed-block-shortcut-support.js +39 -0
- package/dist/editor/install-insert-sole-allowed-block-shortcut-support.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/useful-types.d.ts +3 -0
- package/dist/lib/useful-types.js.map +1 -1
- package/package.json +1 -1
- package/src/editor/insert-sibling-or-child-block-shortcut.tsx +60 -0
- package/src/editor/install-insert-sole-allowed-block-shortcut-support.tsx +51 -0
- package/src/index.ts +3 -0
- package/src/lib/useful-types.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.92.0] - 2026-04-13
|
|
9
|
+
### Added
|
|
10
|
+
- `InsertSiblingOrChildBlockShortcut` and `InsertSiblingOrChildBlockShortcutButton` React components
|
|
11
|
+
- Support for `support.plaudit.insertSoleAllowedBlockShortcut`
|
|
12
|
+
|
|
8
13
|
## [2.91.1] - 2026-04-09
|
|
9
14
|
### Changed
|
|
10
15
|
- Quick rename
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BlockName } from "@plaudit/gutenberg-api-extensions";
|
|
2
|
+
type InsertSoleAllowedBlockShortcutProps = {
|
|
3
|
+
clientId: string;
|
|
4
|
+
targetBlockName: BlockName;
|
|
5
|
+
addedBlockName: BlockName;
|
|
6
|
+
isSelected: boolean;
|
|
7
|
+
props?: Record<string, unknown>;
|
|
8
|
+
buttonText?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const InsertSiblingOrChildBlockShortcut: import("react").MemoExoticComponent<(properties: InsertSoleAllowedBlockShortcutProps) => import("react/jsx-runtime").JSX.Element>;
|
|
11
|
+
export declare const InsertSiblingOrChildBlockShortcutButton: import("react").MemoExoticComponent<(properties: InsertSoleAllowedBlockShortcutProps) => import("react/jsx-runtime").JSX.Element | undefined>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InsertSiblingOrChildBlockShortcutButton = exports.InsertSiblingOrChildBlockShortcut = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const block_editor_1 = require("@wordpress/block-editor");
|
|
6
|
+
const blocks_1 = require("@wordpress/blocks");
|
|
7
|
+
const components_1 = require("@wordpress/components");
|
|
8
|
+
const data_1 = require("@wordpress/data");
|
|
9
|
+
const i18n_1 = require("@wordpress/i18n");
|
|
10
|
+
const react_1 = require("react");
|
|
11
|
+
const emptyProps = {};
|
|
12
|
+
exports.InsertSiblingOrChildBlockShortcut = (0, react_1.memo)(function InsertSiblingOrChildBlockShortcut(properties) {
|
|
13
|
+
return (0, jsx_runtime_1.jsx)(block_editor_1.BlockControls, { group: "other", children: (0, jsx_runtime_1.jsx)(components_1.ToolbarGroup, { children: (0, jsx_runtime_1.jsx)(exports.InsertSiblingOrChildBlockShortcutButton, { ...properties }) }) });
|
|
14
|
+
});
|
|
15
|
+
exports.InsertSiblingOrChildBlockShortcutButton = (0, react_1.memo)(function InsertSiblingOrChildBlockShortcutButton(properties) {
|
|
16
|
+
const { clientId, targetBlockName, addedBlockName, isSelected, props = emptyProps, buttonText = "Add {blockName}" } = properties;
|
|
17
|
+
const targetClientId = (0, data_1.useSelect)((select) => {
|
|
18
|
+
const blockEditorSelect = select(block_editor_1.store);
|
|
19
|
+
if (blockEditorSelect.getBlock(clientId)?.name === targetBlockName) {
|
|
20
|
+
return clientId;
|
|
21
|
+
}
|
|
22
|
+
return blockEditorSelect.getBlockParentsByBlockName(clientId, targetBlockName, true)[0];
|
|
23
|
+
}, [clientId, targetBlockName]);
|
|
24
|
+
if ((0, block_editor_1.useBlockEditingMode)() === "contentOnly" || !isSelected || !targetClientId) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const buttonChildren = (0, i18n_1.__)(buttonText).replaceAll("{blockName}", (0, data_1.select)(blocks_1.store).getBlockType(addedBlockName)?.title ?? (0, i18n_1.__)(`${clientId === targetClientId ? "child" : "sibling"} block`));
|
|
28
|
+
return ((0, jsx_runtime_1.jsx)(components_1.ToolbarButton, { onClick: () => {
|
|
29
|
+
let insertionIndex;
|
|
30
|
+
const blockEditorSelect = (0, data_1.select)(block_editor_1.store);
|
|
31
|
+
if (clientId && clientId !== targetClientId) {
|
|
32
|
+
const closestClients = blockEditorSelect.getBlockParents(clientId, true);
|
|
33
|
+
const targetIndex = closestClients.indexOf(targetClientId);
|
|
34
|
+
insertionIndex = blockEditorSelect.getBlockIndex(closestClients[targetIndex - 1] ?? clientId, targetClientId);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
insertionIndex = -1;
|
|
38
|
+
}
|
|
39
|
+
(0, data_1.dispatch)(block_editor_1.store).insertBlock((0, blocks_1.createBlock)(addedBlockName, props), insertionIndex > -1 ? insertionIndex + 1 : undefined, targetClientId);
|
|
40
|
+
}, children: buttonChildren }));
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=insert-sibling-or-child-block-shortcut.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insert-sibling-or-child-block-shortcut.js","sourceRoot":"","sources":["../../src/editor/insert-sibling-or-child-block-shortcut.tsx"],"names":[],"mappings":";;;;AAAA,0DAAsG;AACtG,8CAAoE;AACpE,sDAAkE;AAClE,0CAA4D;AAC5D,0CAAmC;AAInC,iCAA2B;AAE3B,MAAM,UAAU,GAA4B,EAAE,CAAC;AAWlC,QAAA,iCAAiC,GAAG,IAAA,YAAI,EAAC,SAAS,iCAAiC,CAAC,UAA+C;IAC/I,OAAO,uBAAC,4BAAa,IAAC,KAAK,EAAC,OAAO,YAClC,uBAAC,yBAAY,cACZ,uBAAC,+CAAuC,OAAK,UAAU,GAAI,GAC7C,GACA,CAAA;AACjB,CAAC,CAAC,CAAC;AAEU,QAAA,uCAAuC,GAAG,IAAA,YAAI,EAAC,SAAS,uCAAuC,CAAC,UAA+C;IAC3J,MAAM,EAAC,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,GAAG,UAAU,EAAE,UAAU,GAAG,iBAAiB,EAAC,GAAG,UAAU,CAAC;IAE/H,MAAM,cAAc,GAAG,IAAA,gBAAS,EAAC,CAAC,MAAM,EAAE,EAAE;QAC3C,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAgB,CAAC,CAAC;QACnD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;YACpE,OAAO,QAAQ,CAAC;QACjB,CAAC;QACD,OAAO,iBAAiB,CAAC,0BAA0B,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;IAEhC,IAAI,IAAA,kCAAmB,GAAE,KAAK,aAAa,IAAI,CAAC,UAAU,IAAI,CAAC,cAAc,EAAE,CAAC;QAC/E,OAAO;IACR,CAAC;IAED,MAAM,cAAc,GAAG,IAAA,SAAE,EAAC,UAAU,CAAC,CAAC,UAAU,CAAC,aAAa,EAAE,IAAA,aAAM,EAAC,cAAW,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,IAAA,SAAE,EAAC,GAAG,QAAQ,KAAK,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;IAC7L,OAAO,CACN,uBAAC,0BAAa,IAAC,OAAO,EAAE,GAAG,EAAE;YAC5B,IAAI,cAAsB,CAAC;YAC3B,MAAM,iBAAiB,GAAG,IAAA,aAAM,EAAC,oBAAgB,CAAC,CAAC;YACnD,IAAI,QAAQ,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;gBAC7C,MAAM,cAAc,GAAG,iBAAiB,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBACzE,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAC3D,cAAc,GAAG,iBAAiB,CAAC,aAAa,CAAC,cAAc,CAAC,WAAW,GAAG,CAAC,CAAC,IAAI,QAAQ,EAAE,cAAc,CAAC,CAAC;YAC/G,CAAC;iBAAM,CAAC;gBACP,cAAc,GAAG,CAAC,CAAC,CAAC;YACrB,CAAC;YACD,IAAA,eAAQ,EAAC,oBAAgB,CAAC,CAAC,WAAW,CAAC,IAAA,oBAAW,EAAC,cAAc,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAClJ,CAAC,EAAE,QAAQ,EAAE,cAAc,GAAI,CAC/B,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function installInsertSoleAllowedBlockShortcutSupport(): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installInsertSoleAllowedBlockShortcutSupport = installInsertSoleAllowedBlockShortcutSupport;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const block_editor_1 = require("@wordpress/block-editor");
|
|
6
|
+
const compose_1 = require("@wordpress/compose");
|
|
7
|
+
const data_1 = require("@wordpress/data");
|
|
8
|
+
const hooks_1 = require("@wordpress/hooks");
|
|
9
|
+
const insert_sibling_or_child_block_shortcut_1 = require("./insert-sibling-or-child-block-shortcut");
|
|
10
|
+
function installInsertSoleAllowedBlockShortcutSupport() {
|
|
11
|
+
const namespace = 'plaudit/gutenberg-api-extensions/inject-insert-sole-allowed-block-support';
|
|
12
|
+
const blocksWithInsertSoleAllowedBlockShortcut = {};
|
|
13
|
+
const blocksThatMightBeAbleToInsertSiblings = {};
|
|
14
|
+
(0, hooks_1.addFilter)('blocks.registerBlockType', namespace, (atts) => {
|
|
15
|
+
if (atts.supports?.plaudit?.insertSoleAllowedBlockShortcut) {
|
|
16
|
+
const target = atts.allowedBlocks?.[0];
|
|
17
|
+
if (target) {
|
|
18
|
+
blocksWithInsertSoleAllowedBlockShortcut[atts.name] = target;
|
|
19
|
+
blocksThatMightBeAbleToInsertSiblings[target] = atts.name;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return atts;
|
|
23
|
+
}, 1_000 /* We have this run late to allow for dynamic injection of the supports flag */);
|
|
24
|
+
(0, hooks_1.addFilter)('editor.BlockEdit', namespace, (0, compose_1.createHigherOrderComponent)((BlockEdit) => {
|
|
25
|
+
return function InsertSoleAllowedBlockShortcutSupport(props) {
|
|
26
|
+
const potentialAddedBlockName = blocksWithInsertSoleAllowedBlockShortcut[props.name];
|
|
27
|
+
const toolbarItems = [];
|
|
28
|
+
if (potentialAddedBlockName) {
|
|
29
|
+
toolbarItems.push((0, jsx_runtime_1.jsx)(insert_sibling_or_child_block_shortcut_1.InsertSiblingOrChildBlockShortcut, { clientId: props.clientId, targetBlockName: props.name, addedBlockName: potentialAddedBlockName, isSelected: (0, data_1.select)(block_editor_1.store).getSelectedBlockClientId() === props.clientId }, "add-own-sole-allowed-block"));
|
|
30
|
+
}
|
|
31
|
+
const potentialTargetBlockName = blocksThatMightBeAbleToInsertSiblings[props.name];
|
|
32
|
+
if (potentialTargetBlockName) {
|
|
33
|
+
toolbarItems.push((0, jsx_runtime_1.jsx)(insert_sibling_or_child_block_shortcut_1.InsertSiblingOrChildBlockShortcut, { clientId: props.clientId, targetBlockName: potentialTargetBlockName, addedBlockName: props.name, isSelected: (0, data_1.select)(block_editor_1.store).getSelectedBlockClientId() === props.clientId }, "add-ancestor-sole-allowed-block"));
|
|
34
|
+
}
|
|
35
|
+
return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(BlockEdit, { ...props }), " ", toolbarItems] });
|
|
36
|
+
};
|
|
37
|
+
}, 'plaudit/gutenberg-api-extensions/insert-sole-allowed-block-support'));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=install-insert-sole-allowed-block-shortcut-support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-insert-sole-allowed-block-shortcut-support.js","sourceRoot":"","sources":["../../src/editor/install-insert-sole-allowed-block-shortcut-support.tsx"],"names":[],"mappings":";;AAUA,oGAwCC;;AAlDD,0DAAoE;AACpE,gDAAgE;AAChE,0CAAyC;AACzC,4CAA6C;AAI7C,qGAA6F;AAG7F,SAAgB,4CAA4C;IAC3D,MAAM,SAAS,GAAG,2EAA2E,CAAC;IAC9F,MAAM,wCAAwC,GAA6C,EAAE,CAAC;IAC9F,MAAM,qCAAqC,GAAiC,EAAE,CAAC;IAC/E,IAAA,iBAAS,EAAC,0BAA0B,EAAE,SAAS,EAAE,CAAC,IAAwB,EAAE,EAAE;QAC7E,IAAI,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;YAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,MAAM,EAAE,CAAC;gBACZ,wCAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;gBAC7D,qCAAqC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;YAC3D,CAAC;QACF,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC,EAAE,KAAK,CAAC,+EAA+E,CAAC,CAAC;IAE1F,IAAA,iBAAS,EAAC,kBAAkB,EAAE,SAAS,EACtC,IAAA,oCAA0B,EAAC,CAAC,SAAkD,EAAE,EAAE;QACjF,OAAO,SAAS,qCAAqC,CAAC,KAA2B;YAChF,MAAM,uBAAuB,GAAG,wCAAwC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrF,MAAM,YAAY,GAAgB,EAAE,CAAC;YACrC,IAAI,uBAAuB,EAAE,CAAC;gBAC7B,YAAY,CAAC,IAAI,CAChB,uBAAC,0EAAiC,IACA,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,EAAE,uBAAuB,EAC/H,UAAU,EAAE,IAAA,aAAM,EAAC,oBAAgB,CAAC,CAAC,wBAAwB,EAAE,KAAK,KAAK,CAAC,QAAQ,IAD9E,4BAA4B,CAE/B,CACF,CAAC;YACH,CAAC;YACD,MAAM,wBAAwB,GAAG,qCAAqC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACnF,IAAI,wBAAwB,EAAE,CAAC;gBAC9B,YAAY,CAAC,IAAI,CAChB,uBAAC,0EAAiC,IACK,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,eAAe,EAAE,wBAAwB,EAAE,cAAc,EAAE,KAAK,CAAC,IAAI,EACrI,UAAU,EAAE,IAAA,aAAM,EAAC,oBAAgB,CAAC,CAAC,wBAAwB,EAAE,KAAK,KAAK,CAAC,QAAQ,IAD9E,iCAAiC,CAEpC,CACF,CAAC;YACH,CAAC;YACD,OAAO,6DAAE,uBAAC,SAAS,OAAK,KAAK,GAAI,OAAE,YAAY,IAAI,CAAC;QACrD,CAAC,CAAC;IACH,CAAC,EAAE,oEAAoE,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { store as apiExtensionsStore } from "./lib/gutenberg-api-extensions-stat
|
|
|
3
3
|
export * from "./blocks";
|
|
4
4
|
export * from "./controls";
|
|
5
5
|
export * from "./editor/simple-gutenberg-endpoints-api";
|
|
6
|
+
export * from "./editor/insert-sibling-or-child-block-shortcut";
|
|
6
7
|
export { TemporalLRUCache, useAdoptedStyleSheet } from "./lib/helpers";
|
|
7
8
|
export * from "./lib/modified-fast-deep-equals";
|
|
8
9
|
export * from "./lib/plaudit-icons";
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.endpointsStore = exports.apiExtensionsStore = exports.SectionedCacheStore = exports.useAdoptedStyleSheet = exports.TemporalLRUCache = void 0;
|
|
40
40
|
exports.installGutenbergExtensions = installGutenbergExtensions;
|
|
41
41
|
const simple_native_property_impl_1 = require("./blocks/simple-native-property-impl");
|
|
42
|
+
const install_insert_sole_allowed_block_shortcut_support_1 = require("./editor/install-insert-sole-allowed-block-shortcut-support");
|
|
42
43
|
const simple_gutenberg_endpoints_impl_1 = require("./editor/simple-gutenberg-endpoints-impl");
|
|
43
44
|
Object.defineProperty(exports, "endpointsStore", { enumerable: true, get: function () { return simple_gutenberg_endpoints_impl_1.store; } });
|
|
44
45
|
const gutenberg_api_extensions_state_1 = require("./lib/gutenberg-api-extensions-state");
|
|
@@ -46,6 +47,7 @@ Object.defineProperty(exports, "apiExtensionsStore", { enumerable: true, get: fu
|
|
|
46
47
|
__exportStar(require("./blocks"), exports);
|
|
47
48
|
__exportStar(require("./controls"), exports);
|
|
48
49
|
__exportStar(require("./editor/simple-gutenberg-endpoints-api"), exports);
|
|
50
|
+
__exportStar(require("./editor/insert-sibling-or-child-block-shortcut"), exports);
|
|
49
51
|
var helpers_1 = require("./lib/helpers");
|
|
50
52
|
Object.defineProperty(exports, "TemporalLRUCache", { enumerable: true, get: function () { return helpers_1.TemporalLRUCache; } });
|
|
51
53
|
Object.defineProperty(exports, "useAdoptedStyleSheet", { enumerable: true, get: function () { return helpers_1.useAdoptedStyleSheet; } });
|
|
@@ -59,6 +61,7 @@ function installGutenbergExtensions() {
|
|
|
59
61
|
(0, gutenberg_api_extensions_state_1.registerStore)();
|
|
60
62
|
(0, simple_native_property_impl_1.installSimpleNativePropertiesSupport)();
|
|
61
63
|
(0, simple_gutenberg_endpoints_impl_1.installSimpleGutenbergApisSupport)();
|
|
64
|
+
(0, install_insert_sole_allowed_block_shortcut_support_1.installInsertSoleAllowedBlockShortcutSupport)();
|
|
62
65
|
}
|
|
63
66
|
}
|
|
64
67
|
(function (installGutenbergExtensions) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,gEAQC;AA1BD,sFAA0F;AAC1F,oIAAyH;AACzH,8FAAoH;AAcxF,+FAdwB,uCAAc,OAcxB;AAb1C,yFAAgG;AAaxF,mGAbwB,sCAAkB,OAaxB;AAX1B,2CAAyB;AACzB,6CAA2B;AAC3B,0EAAwD;AACxD,kFAAgE;AAChE,yCAAqE;AAA7D,2GAAA,gBAAgB,OAAA;AAAE,+GAAA,oBAAoB,OAAA;AAC9C,kEAAgD;AAChD,sDAAoC;AACpC,mFAAmE;AACnE,iDAA+B;AAK/B,SAAgB,0BAA0B;IACzC,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,CAAC;QACxC,0BAA0B,CAAC,MAAM,GAAG,IAAI,CAAC;QACzC,IAAA,8CAAa,GAAE,CAAC;QAChB,IAAA,kEAAoC,GAAE,CAAC;QACvC,IAAA,mEAAiC,GAAE,CAAC;QACpC,IAAA,iGAA4C,GAAE,CAAC;IAChD,CAAC;AACF,CAAC;AACD,WAAiB,0BAA0B;IAC/B,iCAAM,GAAY,KAAK,CAAC;AACpC,CAAC,EAFgB,0BAA0B,0CAA1B,0BAA0B,QAE1C"}
|
|
@@ -47,6 +47,9 @@ export type RegisterBlockAttrs<T extends Record<string, any> = {}> = {
|
|
|
47
47
|
group: any;
|
|
48
48
|
} | BlockJsonNativePropsConfig | undefined;
|
|
49
49
|
supports: BlockSupports & Record<Exclude<string, keyof BlockSupports>, any>;
|
|
50
|
+
allowedBlocks?: BlockName[];
|
|
51
|
+
ancestor?: BlockName[];
|
|
52
|
+
parent?: BlockName[];
|
|
50
53
|
};
|
|
51
54
|
export declare function isBlockJsonNativePropsConfig(thing: unknown): thing is BlockJsonNativePropsConfig;
|
|
52
55
|
export type NonEmptyArray<T> = [T, ...T[]];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useful-types.js","sourceRoot":"","sources":["../../src/lib/useful-types.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"useful-types.js","sourceRoot":"","sources":["../../src/lib/useful-types.ts"],"names":[],"mappings":";;AAkCA,oEAEC;AAGD,0CAEC;AAPD,SAAgB,4BAA4B,CAAC,KAAc;IAC1D,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AAClG,CAAC;AAGD,SAAgB,eAAe,CAAI,GAAuB;IACzD,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;AAChC,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {BlockControls, store as blockEditorStore, useBlockEditingMode} from "@wordpress/block-editor";
|
|
2
|
+
import {store as blocksStore, createBlock} from "@wordpress/blocks";
|
|
3
|
+
import {ToolbarButton, ToolbarGroup} from "@wordpress/components";
|
|
4
|
+
import {dispatch, select, useSelect} from "@wordpress/data";
|
|
5
|
+
import {__} from "@wordpress/i18n";
|
|
6
|
+
|
|
7
|
+
import type {BlockName} from "@plaudit/gutenberg-api-extensions";
|
|
8
|
+
|
|
9
|
+
import {memo} from "react";
|
|
10
|
+
|
|
11
|
+
const emptyProps: Record<string, unknown> = {};
|
|
12
|
+
|
|
13
|
+
type InsertSoleAllowedBlockShortcutProps = {
|
|
14
|
+
clientId: string,
|
|
15
|
+
targetBlockName: BlockName,
|
|
16
|
+
addedBlockName: BlockName,
|
|
17
|
+
isSelected: boolean,
|
|
18
|
+
props?: Record<string, unknown>,
|
|
19
|
+
buttonText?: string
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const InsertSiblingOrChildBlockShortcut = memo(function InsertSiblingOrChildBlockShortcut(properties: InsertSoleAllowedBlockShortcutProps) {
|
|
23
|
+
return <BlockControls group="other">
|
|
24
|
+
<ToolbarGroup>
|
|
25
|
+
<InsertSiblingOrChildBlockShortcutButton {...properties} />
|
|
26
|
+
</ToolbarGroup>
|
|
27
|
+
</BlockControls>
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const InsertSiblingOrChildBlockShortcutButton = memo(function InsertSiblingOrChildBlockShortcutButton(properties: InsertSoleAllowedBlockShortcutProps) {
|
|
31
|
+
const {clientId, targetBlockName, addedBlockName, isSelected, props = emptyProps, buttonText = "Add {blockName}"} = properties;
|
|
32
|
+
|
|
33
|
+
const targetClientId = useSelect((select) => {
|
|
34
|
+
const blockEditorSelect = select(blockEditorStore);
|
|
35
|
+
if (blockEditorSelect.getBlock(clientId)?.name === targetBlockName) {
|
|
36
|
+
return clientId;
|
|
37
|
+
}
|
|
38
|
+
return blockEditorSelect.getBlockParentsByBlockName(clientId, targetBlockName, true)[0];
|
|
39
|
+
}, [clientId, targetBlockName]);
|
|
40
|
+
|
|
41
|
+
if (useBlockEditingMode() === "contentOnly" || !isSelected || !targetClientId) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const buttonChildren = __(buttonText).replaceAll("{blockName}", select(blocksStore).getBlockType(addedBlockName)?.title ?? __(`${clientId === targetClientId ? "child" : "sibling"} block`));
|
|
46
|
+
return (
|
|
47
|
+
<ToolbarButton onClick={() => {
|
|
48
|
+
let insertionIndex: number;
|
|
49
|
+
const blockEditorSelect = select(blockEditorStore);
|
|
50
|
+
if (clientId && clientId !== targetClientId) {
|
|
51
|
+
const closestClients = blockEditorSelect.getBlockParents(clientId, true);
|
|
52
|
+
const targetIndex = closestClients.indexOf(targetClientId);
|
|
53
|
+
insertionIndex = blockEditorSelect.getBlockIndex(closestClients[targetIndex - 1] ?? clientId, targetClientId);
|
|
54
|
+
} else {
|
|
55
|
+
insertionIndex = -1;
|
|
56
|
+
}
|
|
57
|
+
dispatch(blockEditorStore).insertBlock(createBlock(addedBlockName, props), insertionIndex > -1 ? insertionIndex + 1 : undefined, targetClientId);
|
|
58
|
+
}} children={buttonChildren} />
|
|
59
|
+
);
|
|
60
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { store as blockEditorStore } from "@wordpress/block-editor";
|
|
2
|
+
import { createHigherOrderComponent } from "@wordpress/compose";
|
|
3
|
+
import { select } from "@wordpress/data";
|
|
4
|
+
import { addFilter } from "@wordpress/hooks";
|
|
5
|
+
|
|
6
|
+
import type { FunctionComponent, ReactNode } from "react";
|
|
7
|
+
|
|
8
|
+
import { InsertSiblingOrChildBlockShortcut } from "./insert-sibling-or-child-block-shortcut";
|
|
9
|
+
import type { ActualBlockEditProps, BlockName, RegisterBlockAttrs } from "../lib/useful-types";
|
|
10
|
+
|
|
11
|
+
export function installInsertSoleAllowedBlockShortcutSupport() {
|
|
12
|
+
const namespace = 'plaudit/gutenberg-api-extensions/inject-insert-sole-allowed-block-support';
|
|
13
|
+
const blocksWithInsertSoleAllowedBlockShortcut: Record<BlockName, BlockName | undefined> = {};
|
|
14
|
+
const blocksThatMightBeAbleToInsertSiblings: Record<BlockName, BlockName> = {};
|
|
15
|
+
addFilter('blocks.registerBlockType', namespace, (atts: RegisterBlockAttrs) => {
|
|
16
|
+
if (atts.supports?.plaudit?.insertSoleAllowedBlockShortcut) {
|
|
17
|
+
const target = atts.allowedBlocks?.[0];
|
|
18
|
+
if (target) {
|
|
19
|
+
blocksWithInsertSoleAllowedBlockShortcut[atts.name] = target;
|
|
20
|
+
blocksThatMightBeAbleToInsertSiblings[target] = atts.name;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return atts;
|
|
24
|
+
}, 1_000 /* We have this run late to allow for dynamic injection of the supports flag */);
|
|
25
|
+
|
|
26
|
+
addFilter('editor.BlockEdit', namespace,
|
|
27
|
+
createHigherOrderComponent((BlockEdit: FunctionComponent<ActualBlockEditProps>) => {
|
|
28
|
+
return function InsertSoleAllowedBlockShortcutSupport(props: ActualBlockEditProps) {
|
|
29
|
+
const potentialAddedBlockName = blocksWithInsertSoleAllowedBlockShortcut[props.name];
|
|
30
|
+
const toolbarItems: ReactNode[] = [];
|
|
31
|
+
if (potentialAddedBlockName) {
|
|
32
|
+
toolbarItems.push(
|
|
33
|
+
<InsertSiblingOrChildBlockShortcut
|
|
34
|
+
key="add-own-sole-allowed-block" clientId={props.clientId} targetBlockName={props.name} addedBlockName={potentialAddedBlockName}
|
|
35
|
+
isSelected={select(blockEditorStore).getSelectedBlockClientId() === props.clientId}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const potentialTargetBlockName = blocksThatMightBeAbleToInsertSiblings[props.name];
|
|
40
|
+
if (potentialTargetBlockName) {
|
|
41
|
+
toolbarItems.push(
|
|
42
|
+
<InsertSiblingOrChildBlockShortcut
|
|
43
|
+
key="add-ancestor-sole-allowed-block" clientId={props.clientId} targetBlockName={potentialTargetBlockName} addedBlockName={props.name}
|
|
44
|
+
isSelected={select(blockEditorStore).getSelectedBlockClientId() === props.clientId}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return <><BlockEdit {...props} /> {toolbarItems}</>;
|
|
49
|
+
};
|
|
50
|
+
}, 'plaudit/gutenberg-api-extensions/insert-sole-allowed-block-support'));
|
|
51
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {installSimpleNativePropertiesSupport} from "./blocks/simple-native-property-impl";
|
|
2
|
+
import {installInsertSoleAllowedBlockShortcutSupport} from "./editor/install-insert-sole-allowed-block-shortcut-support";
|
|
2
3
|
import {installSimpleGutenbergApisSupport, store as endpointsStore} from "./editor/simple-gutenberg-endpoints-impl";
|
|
3
4
|
import {registerStore, store as apiExtensionsStore} from "./lib/gutenberg-api-extensions-state";
|
|
4
5
|
|
|
5
6
|
export * from "./blocks";
|
|
6
7
|
export * from "./controls";
|
|
7
8
|
export * from "./editor/simple-gutenberg-endpoints-api";
|
|
9
|
+
export * from "./editor/insert-sibling-or-child-block-shortcut";
|
|
8
10
|
export {TemporalLRUCache, useAdoptedStyleSheet} from "./lib/helpers";
|
|
9
11
|
export * from "./lib/modified-fast-deep-equals";
|
|
10
12
|
export * from "./lib/plaudit-icons";
|
|
@@ -20,6 +22,7 @@ export function installGutenbergExtensions() {
|
|
|
20
22
|
registerStore();
|
|
21
23
|
installSimpleNativePropertiesSupport();
|
|
22
24
|
installSimpleGutenbergApisSupport();
|
|
25
|
+
installInsertSoleAllowedBlockShortcutSupport();
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
export namespace installGutenbergExtensions {
|
package/src/lib/useful-types.ts
CHANGED
|
@@ -28,7 +28,8 @@ export type BlockJsonNativePropsConfig = {
|
|
|
28
28
|
export type RegisterBlockAttrs<T extends Record<string, any> = {}> = {
|
|
29
29
|
name: BlockName, attributes: Block<T>['attributes'], usesContext?: string[],
|
|
30
30
|
plaudit?: "native"|boolean|{group: any}|BlockJsonNativePropsConfig|undefined,
|
|
31
|
-
supports: BlockSupports&Record<Exclude<string, keyof BlockSupports>, any
|
|
31
|
+
supports: BlockSupports&Record<Exclude<string, keyof BlockSupports>, any>,
|
|
32
|
+
allowedBlocks?: BlockName[], ancestor?: BlockName[], parent?: BlockName[],
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
export function isBlockJsonNativePropsConfig(thing: unknown): thing is BlockJsonNativePropsConfig {
|