@plaudit/gutenberg-api-extensions 2.83.0 → 2.84.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/blocks/SNPGroupComponent.js.map +1 -1
  3. package/dist/blocks/common-native-property-constructors.js +3 -2
  4. package/dist/blocks/common-native-property-constructors.js.map +1 -1
  5. package/dist/blocks/data-controller/actions.d.ts +135 -0
  6. package/dist/blocks/data-controller/actions.js +19 -0
  7. package/dist/blocks/data-controller/actions.js.map +1 -0
  8. package/dist/blocks/data-controller/reducer.d.ts +4 -0
  9. package/dist/blocks/data-controller/reducer.js +143 -0
  10. package/dist/blocks/data-controller/reducer.js.map +1 -0
  11. package/dist/blocks/data-controller/trigger-handlers.d.ts +140 -0
  12. package/dist/blocks/data-controller/trigger-handlers.js +117 -0
  13. package/dist/blocks/data-controller/trigger-handlers.js.map +1 -0
  14. package/dist/blocks/data-controller/utils.d.ts +43 -0
  15. package/dist/blocks/data-controller/utils.js +359 -0
  16. package/dist/blocks/data-controller/utils.js.map +1 -0
  17. package/dist/blocks/data-controller.d.ts +4 -37
  18. package/dist/blocks/data-controller.js +33 -604
  19. package/dist/blocks/data-controller.js.map +1 -1
  20. package/dist/blocks/layered-styles-impl.js +9 -8
  21. package/dist/blocks/layered-styles-impl.js.map +1 -1
  22. package/dist/blocks/layout/NodeContext.js +3 -3
  23. package/dist/blocks/layout/NodeContext.js.map +1 -1
  24. package/dist/blocks/simple-native-property-api.d.ts +9 -7
  25. package/dist/blocks/simple-native-property-api.js.map +1 -1
  26. package/dist/blocks/simple-native-property-impl.js +26 -24
  27. package/dist/blocks/simple-native-property-impl.js.map +1 -1
  28. package/dist/blocks/snp-data-store.d.ts +9 -6
  29. package/dist/blocks/snp-data-store.js +17 -12
  30. package/dist/blocks/snp-data-store.js.map +1 -1
  31. package/dist/controls/FullSizeToggleControl.d.ts +1 -1
  32. package/dist/controls/FullSizeToggleControl.js.map +1 -1
  33. package/dist/lib/gutenberg-api-extensions-state/layered-block-styles-logic.js +12 -12
  34. package/dist/lib/gutenberg-api-extensions-state/layered-block-styles-logic.js.map +1 -1
  35. package/dist/lib/gutenberg-api-extensions-state/snp-logic.js +2 -2
  36. package/dist/lib/gutenberg-api-extensions-state/snp-logic.js.map +1 -1
  37. package/package.json +7 -7
  38. package/src/blocks/SNPGroupComponent.tsx +1 -1
  39. package/src/blocks/common-native-property-constructors.tsx +3 -2
  40. package/src/blocks/data-controller/actions.ts +20 -0
  41. package/src/blocks/data-controller/reducer.ts +149 -0
  42. package/src/blocks/data-controller/trigger-handlers.ts +138 -0
  43. package/src/blocks/data-controller/utils.ts +339 -0
  44. package/src/blocks/data-controller.ts +38 -605
  45. package/src/blocks/layered-styles-impl.ts +10 -9
  46. package/src/blocks/layout/NodeContext.tsx +3 -3
  47. package/src/blocks/simple-native-property-api.ts +10 -9
  48. package/src/blocks/simple-native-property-impl.tsx +26 -24
  49. package/src/blocks/snp-data-store.ts +22 -13
  50. package/src/controls/FullSizeToggleControl.tsx +3 -3
  51. package/src/lib/gutenberg-api-extensions-state/layered-block-styles-logic.ts +12 -11
  52. package/src/lib/gutenberg-api-extensions-state/snp-logic.ts +2 -2
@@ -1,5 +1,6 @@
1
1
  import {select} from "@wordpress/data";
2
2
 
3
+ import {store as gutenbergApiExtensionsStore} from "../lib/gutenberg-api-extensions-state";
3
4
  import type {ActualBlockEditProps} from "../lib/useful-types";
4
5
  import type {PDSimpleNativeProperty} from "./simple-native-property-api";
5
6
  import {makeHasPropClassName} from "./simple-native-property-impl";
@@ -8,20 +9,21 @@ import {SNPDataStore} from "./snp-data-store";
8
9
  export class LayeredStylesDataStore extends SNPDataStore {
9
10
  getAttribute(name: string): any {
10
11
  if (name.startsWith("__plaudit/")) {
11
- return this.blockEditProps.attributes[name];
12
+ return this.getRawBlockAttributes()[name];
12
13
  }
13
- const layer = select('plaudit/gutenberg-api-extensions').blockStylesLayer(this.blockEditProps.name, name);
14
+ const layer = select(gutenbergApiExtensionsStore).blockStylesLayer(this.blockName, name);
14
15
  if (layer === undefined) {
15
16
  return undefined;
16
17
  }
17
- return extractStyleLayerValueFromAttributes(this.blockEditProps.attributes, layer.name) ?? layer.default;
18
+
19
+ return extractStyleLayerValueFromAttributes(this.getRawBlockAttributes(), layer.name) ?? layer.default;
18
20
  }
19
21
  setAttribute(name: string, rawValue: any) {
20
22
  if (name.startsWith("__plaudit/")) {
21
- this.blockEditProps.setAttributes({[name]: rawValue});
23
+ this.setRawBlockAttributes({[name]: rawValue});
22
24
  return;
23
25
  }
24
- const layers = select('plaudit/gutenberg-api-extensions').blockStylesLayers(this.blockEditProps.name);
26
+ const layers = select(gutenbergApiExtensionsStore).blockStylesLayers(this.blockName);
25
27
  if (layers === undefined) {
26
28
  return;
27
29
  }
@@ -29,14 +31,13 @@ export class LayeredStylesDataStore extends SNPDataStore {
29
31
  if (layer === undefined) {
30
32
  return;
31
33
  }
32
-
33
- const className = this.blockEditProps.attributes['className'];
34
+ const className = this.getRawBlockAttributes()['className'];
34
35
 
35
36
  const value = rawValue?.toString() || (layer.default ?? '');
36
37
  const currentLayerClassPrefix = `style-${name}-`;
37
38
  if (typeof className !== 'string' || !className) {
38
39
  if (value.length) {
39
- this.blockEditProps.setAttributes({
40
+ this.setRawBlockAttributes({
40
41
  className: "styleProperty" in layer && layer.styleProperty
41
42
  ? `${currentLayerClassPrefix}${value} ${makeHasPropClassName(layer.name)}`
42
43
  : `${currentLayerClassPrefix}${value}`
@@ -44,7 +45,7 @@ export class LayeredStylesDataStore extends SNPDataStore {
44
45
  }
45
46
  return;
46
47
  }
47
- this.blockEditProps.setAttributes({className: this.incorporateLayerValue(Object.values(layers), layer, name, value, className)});
48
+ this.setRawBlockAttributes({className: this.incorporateLayerValue(Object.values(layers), layer, name, value, className)});
48
49
  }
49
50
 
50
51
  private incorporateLayerValue(layers: PDSimpleNativeProperty[], currentLayer: PDSimpleNativeProperty, name: string, value: string, className: string): string {
@@ -19,15 +19,15 @@ function makeNodeContextValue(path: NodePath, dataController: DataController): N
19
19
  const value = dataController.getValue(path);
20
20
  const node = dataController.getNode(path);
21
21
  // We memoize actions separately to reduce later re-render calls
22
- const actions = useMemo<NodeContextValueActions>(() => ({
22
+ const memoizedActions = useMemo<NodeContextValueActions>(() => ({
23
23
  setValue: value => dataController.setValue(path, value),
24
24
  addNode: (name, value) => dataController.addNode([...path, name], value),
25
25
  removeNode: name => dataController.removeNode([...path, name]),
26
26
  moveNode: indices => dataController.moveNode(path, indices),
27
- validateNode: () => dataController.dispatch({type: "validateNode", path})
27
+ validateNode: () => dataController.validateNode(path)
28
28
  }), [path, dataController]);
29
29
  // We can skip testing path and dataController because we're checking actions
30
- return useMemo(() => ({path, dataController, rendered: node.rendered ?? true, validationError: node.validationError, value, ...actions}), [actions, node, value]);
30
+ return useMemo(() => ({path, dataController, rendered: node.rendered ?? true, validationError: node.validationError, value, ...memoizedActions}), [memoizedActions, node, value]);
31
31
  }
32
32
 
33
33
  export function useNodeContext(action: string): NodeContextValue {
@@ -1,13 +1,11 @@
1
- import type {configureStore} from "@reduxjs/toolkit/src/configureStore";
2
-
3
1
  import type {createSlotFill} from "@wordpress/components";
4
2
  import {dispatch, select} from "@wordpress/data";
5
3
 
6
4
  import type {CSNPConfig} from "./csnp-api";
7
5
  import type {Condition} from "./conditions";
8
- import type {DataControllerActions, DCNode, DCStoreState} from "./data-controller";
6
+ import type {DCNode} from "./data-controller";
9
7
  import {installGutenbergExtensions} from "../index";
10
- import type {ActualBlockEditProps, BlockName} from "../lib/useful-types";
8
+ import type {BlockName} from "../lib/useful-types";
11
9
  import type {HydratedLaidOutProperties} from "./simple-native-property-internal-shared";
12
10
 
13
11
  import type {ReactElement, ReactNode} from "react";
@@ -15,28 +13,30 @@ import type {ReactElement, ReactNode} from "react";
15
13
  export type InspectorPanelGroup = 'layered-styles'|'post'|'default'|'advanced'|'background'|'border'|'color'|'dimensions'|'effects'|'filter'|'list'|'position'|'settings'|'styles'|'typography';
16
14
  export type {Condition, ConditionFunction, ConditionStruct} from './conditions';
17
15
 
18
- export interface DataStore<B = unknown> {
16
+ export interface DataStore {
17
+ readonly id: string;
19
18
  getValue(name: string): any;
20
19
  setValue(name: string, value: any): void;
21
20
 
22
- reattach(blockEditProps: B, attributeCache: Record<string, any>): DataStore<B>;
21
+ reattach(attributeCache: Record<string, any>): void;
23
22
 
24
23
  handlesProperty(name: string): boolean;
25
24
 
26
25
  addProperty(property: HydratedSimpleNativeProperty, writeThroughOnUndefined?: boolean): void;
27
-
28
- blockEditProps: ActualBlockEditProps;
29
26
  }
30
27
  export type RawPath = (string|number)[];
31
28
  export type NodePath = [string, ...(string|number)[]];
32
29
  export type DataController = {
33
- dispatch: ReturnType<typeof configureStore<DCStoreState, DataControllerActions, []>>['dispatch'],
34
30
  getDataStore(property: string, required: true): DataStore,
35
31
  getDataStore(property: string, required?: undefined|false): DataStore|undefined,
36
32
  getDataStore(property: string, required?: boolean): DataStore|undefined,
37
33
  getAllDataStores(): DataStore[],
38
34
  makePropertyValueResolver(contextPath: RawPath): (propertyPath: RawPath) => any,
39
35
 
36
+ checkConditions(): void,
37
+ validateNodes(): void,
38
+ commitBatchAddedProperties(): void,
39
+
40
40
  getValue(path: NodePath): any|undefined,
41
41
  setValue(path: NodePath, value: any): void,
42
42
 
@@ -44,6 +44,7 @@ export type DataController = {
44
44
  addNode(path: NodePath, value?: any): void,
45
45
  removeNode(path: NodePath): void,
46
46
  moveNode(path: NodePath, indices: {from: number, to: number}|{from: string, to: string}): void,
47
+ validateNode(path: NodePath): void,
47
48
 
48
49
  hasRenderedNode(properties: HydratedLaidOutProperties): boolean,
49
50
  hasValidationErrors(properties?: HydratedLaidOutProperties): boolean,
@@ -10,6 +10,7 @@ import {DataControllerManager, createDataControllerManager} from "./data-control
10
10
  import {extractStyleLayerValueFromAttributes, LayeredStylesDataStore} from "./layered-styles-impl";
11
11
  import {TabsRoot} from "./layout/TabsRoot";
12
12
  import {PanelRoot} from "./layout/PanelRoot";
13
+ import {store as gutenbergApiExtensionsStore} from "../lib/gutenberg-api-extensions-state";
13
14
  import {ActualBEPAttrs, ActualBlockEditProps, ActualBlockListBlockProps, isBlockJsonNativePropsConfig, RegisterBlockAttrs} from "../lib/useful-types";
14
15
  import {PathError} from "./PathError";
15
16
  import type {DataController, DataStore, HydratedSimpleNativeProperty, InspectorPanelGroup} from "./simple-native-property-api";
@@ -19,11 +20,11 @@ import {SNPTreeContext} from "./SNPTreeContext";
19
20
 
20
21
  class AttributeDataStore extends SNPDataStore {
21
22
  public getAttribute(name: string): any {
22
- return this.blockEditProps.attributes[name];
23
+ return this.getRawBlockAttributes()[name];
23
24
  }
24
25
 
25
26
  public setAttribute(name: string, value: any) {
26
- this.blockEditProps.setAttributes(name === 'className' ? {className: value?.toString()} : {[name]: value});
27
+ this.setRawBlockAttributes(name === 'className' ? {className: value?.toString()} : {[name]: value});
27
28
  }
28
29
  }
29
30
 
@@ -43,18 +44,18 @@ export function installSimpleNativePropertiesSupport() {
43
44
  if (registeredBlocks.has(atts.name)) {
44
45
  isPlauditNative = registeredBlocks.get(atts.name)!;
45
46
  } else {
46
- dispatch('plaudit/gutenberg-api-extensions').recordBaselineBlockAttrs(atts);
47
+ dispatch(gutenbergApiExtensionsStore).recordBaselineBlockAttrs(atts);
47
48
  if ((isPlauditNative = isBlockJsonNativePropsConfig(atts.plaudit)) && atts.plaudit.properties !== undefined
48
49
  && (Array.isArray(atts.plaudit.properties) ? atts.plaudit.properties.length : atts.plaudit.properties)
49
50
  ) {
50
- dispatch('plaudit/gutenberg-api-extensions').addProperties(atts.name, atts.plaudit.properties);
51
+ dispatch(gutenbergApiExtensionsStore).addProperties(atts.name, atts.plaudit.properties);
51
52
  }
52
53
  registeredBlocks.set(atts.name, isPlauditNative);
53
54
  }
54
55
  //TODO: Figure out some way to re-register a block when its attributes are changed
55
- const blockSimpleNativePanelsAndTabs = select('plaudit/gutenberg-api-extensions').preppedProperties(atts.name);
56
+ const blockSimpleNativePanelsAndTabs = select(gutenbergApiExtensionsStore).preppedProperties(atts.name);
56
57
  if (blockSimpleNativePanelsAndTabs) {
57
- const extraPropTransforms = select('plaudit/gutenberg-api-extensions').extraPropTransforms(atts.name) ?? {};
58
+ const extraPropTransforms = select(gutenbergApiExtensionsStore).extraPropTransforms(atts.name) ?? {};
58
59
  const attsAttributes = {...atts.attributes};
59
60
  if (isPlauditNative && Object.values(extraPropTransforms).some(cfg => cfg.styleProperty)) {
60
61
  attsAttributes['__plaudit/computed-style-attr'] = {type: "object"};
@@ -86,7 +87,7 @@ export function installSimpleNativePropertiesSupport() {
86
87
 
87
88
  addFilter('editor.BlockEdit', 'plaudit/gutenberg-api-extensions/simple-native-properties',
88
89
  createHigherOrderComponent(BlockEdit => (blockEditProps: ActualBlockEditProps) => {
89
- const blockSimpleNativePanelsAndTabs = select('plaudit/gutenberg-api-extensions').preppedProperties(blockEditProps.name);
90
+ const blockSimpleNativePanelsAndTabs = select(gutenbergApiExtensionsStore).preppedProperties(blockEditProps.name);
90
91
  if (!blockSimpleNativePanelsAndTabs) {
91
92
  return <BlockEdit {...blockEditProps} />;
92
93
  }
@@ -121,7 +122,7 @@ export function installSimpleNativePropertiesSupport() {
121
122
  addFilter('editor.BlockListBlock', 'plaudit/gutenberg-api-extensions/simple-native-properties',
122
123
  createHigherOrderComponent(BlockListBlock => (props: ActualBlockListBlockProps) => {
123
124
  const wrapperProps: {className?: string, style?: Record<string, unknown>} = {...props.wrapperProps};
124
- const extraPropTransforms = select('plaudit/gutenberg-api-extensions').computedExtraPropTransforms(props.name);
125
+ const extraPropTransforms = select(gutenbergApiExtensionsStore).computedExtraPropTransforms(props.name);
125
126
  if (!extraPropTransforms || !extraPropTransforms.appliesInEditor) {
126
127
  const dataController = dataControllerManager.getDataController(props.clientId);
127
128
  if (!dataController) {
@@ -130,7 +131,7 @@ export function installSimpleNativePropertiesSupport() {
130
131
 
131
132
  const hasValidationError = dataController.hasValidationErrors();
132
133
  dataControllerManager.notifyOfValidationErrorStatusChange(props.clientId, hasValidationError);
133
- dataController.dispatch({type: "checkConditions"}); // We don't want to wrap this in a useEffect because this function is already only called when necessary.
134
+ dataController.checkConditions(); // We don't want to wrap this in a useEffect because this function is already only called when necessary.
134
135
 
135
136
  if (hasValidationError) {
136
137
  //TODO: Should I set isValid?
@@ -150,7 +151,7 @@ export function installSimpleNativePropertiesSupport() {
150
151
 
151
152
  const hasValidationError = dataController.hasValidationErrors();
152
153
  dataControllerManager.notifyOfValidationErrorStatusChange(props.clientId, hasValidationError);
153
- dataController.dispatch({type: "checkConditions"}); // We don't want to wrap this in a useEffect because this function is already only called when necessary.
154
+ dataController.checkConditions(); // We don't want to wrap this in a useEffect because this function is already only called when necessary.
154
155
 
155
156
  if (hasValidationError) {
156
157
  //TODO: Should I set isValid?
@@ -169,7 +170,7 @@ export function installSimpleNativePropertiesSupport() {
169
170
  if (isBlockJsonNativePropsConfig(blockType.plaudit)) {
170
171
  return props;
171
172
  }
172
- const extraPropTransforms = select('plaudit/gutenberg-api-extensions').computedExtraPropTransforms(blockType.name);
173
+ const extraPropTransforms = select(gutenbergApiExtensionsStore).computedExtraPropTransforms(blockType.name);
173
174
 
174
175
  return extraPropTransforms && extraPropTransforms.appliesInEditor ? produce(props, draft => {
175
176
  applyExtraPropTransforms(extraPropTransforms.transforms, attributes, draft);
@@ -249,39 +250,40 @@ function applyExtraPropTransforms(
249
250
  }
250
251
 
251
252
  function makeDataStoreForPanelOrTab(
252
- blockEditProps: ActualBlockEditProps, group: string|undefined, attributeCache: Record<string, any>, dataStoreTypeOverride?: 'layered-styles'|'attribute'
253
+ blockEditProps: ActualBlockEditProps, group: string|undefined, attributeCache: Record<string, any>, identifier: string, dataStoreTypeOverride?: 'layered-styles'|'attribute'
253
254
  ) {
255
+ const args = [blockEditProps, attributeCache, `${blockEditProps.clientId}-${identifier}`] as const;
254
256
  if (dataStoreTypeOverride) {
255
- return dataStoreTypeOverride === 'layered-styles' ? new LayeredStylesDataStore(blockEditProps, attributeCache) : new AttributeDataStore(blockEditProps, attributeCache);
257
+ return dataStoreTypeOverride === 'layered-styles' ? new LayeredStylesDataStore(...args) : new AttributeDataStore(...args);
256
258
  }
257
- return group === 'layered-styles' ? new LayeredStylesDataStore(blockEditProps, attributeCache) : new AttributeDataStore(blockEditProps, attributeCache);
259
+ return group === 'layered-styles' ? new LayeredStylesDataStore(...args) : new AttributeDataStore(...args);
258
260
  }
259
261
  type SNPPropsWrapperProps = {blockSimpleNativePanelsAndTabs: PreppedSimpleNativePanelsAndTabs, blockEditProps: ActualBlockEditProps, dataController: DataController};
260
262
  function SNPPropsWrapper({blockSimpleNativePanelsAndTabs, blockEditProps, dataController}: SNPPropsWrapperProps) {
261
263
  useMemo(() => {
262
264
  const attributeCache = Object.create(null);
263
- for (const [, panel] of blockSimpleNativePanelsAndTabs.panels) {
264
- const dataStore = makeDataStoreForPanelOrTab(blockEditProps, panel.group, attributeCache, panel.dataStoreTypeOverride);
265
+ for (const [identifier, panel] of blockSimpleNativePanelsAndTabs.panels) {
266
+ const dataStore = makeDataStoreForPanelOrTab(blockEditProps, panel.group, attributeCache, identifier, panel.dataStoreTypeOverride);
265
267
  dataController.addProperties(panel.properties, dataStore, true);
266
268
  }
267
- for (const [group, [_, tabs]] of Object.entries(blockSimpleNativePanelsAndTabs.tabs)) {
268
- const dataStore = makeDataStoreForPanelOrTab(blockEditProps, group, attributeCache);
269
+ for (const [group, [identifier, tabs]] of Object.entries(blockSimpleNativePanelsAndTabs.tabs)) {
270
+ const dataStore = makeDataStoreForPanelOrTab(blockEditProps, group, attributeCache, identifier);
269
271
  for (const tab of Object.values(tabs)) {
270
272
  for (const panel of tab.items) {
271
273
  dataController.addProperties(panel.properties, dataStore, true);
272
274
  }
273
275
  }
274
276
  }
275
- dataController.dispatch({type: "checkConditions"});
276
- dataController.dispatch({type: "validateNodes"});
277
- dataController.dispatch({type: "commitBatchAddedProperties"});
277
+ dataController.checkConditions();
278
+ dataController.validateNodes();
279
+ dataController.commitBatchAddedProperties();
278
280
  }, [blockSimpleNativePanelsAndTabs, dataController]); // We don't depend on blockEditProps here - that is handled by the following useEffect
279
281
 
280
282
  // We have to reattach dataStores in the useMemo segment in order for Panel- and Tab-level conditions to work
281
283
  useMemo(() => {
282
284
  const attributeCache = Object.create(null);
283
285
  for (const dataStore of dataController.getAllDataStores()) {
284
- dataStore.reattach(blockEditProps, attributeCache);
286
+ dataStore.reattach(attributeCache);
285
287
  }
286
288
  }, [dataController.getAllDataStores(), blockEditProps]);
287
289
 
@@ -290,8 +292,8 @@ function SNPPropsWrapper({blockSimpleNativePanelsAndTabs, blockEditProps, dataCo
290
292
  if (dataController.getWasChangedByManagedControl()) {
291
293
  dataController.markManagedControlChangeHandled();
292
294
  } else{
293
- dataController.dispatch({type: "checkConditions"});
294
- dataController.dispatch({type: "validateNodes"});
295
+ dataController.checkConditions();
296
+ dataController.validateNodes();
295
297
  }
296
298
  }, [dataController.getAllDataStores(), blockEditProps]);
297
299
 
@@ -1,19 +1,25 @@
1
- import type {ActualBlockEditProps} from "../lib/useful-types";
1
+ import {store as blockEditorStore} from "@wordpress/block-editor";
2
+ import {dispatch, select} from "@wordpress/data";
3
+
4
+ import type {ActualBlockEditProps, BlockName} from "../lib/useful-types";
2
5
  import type {DataStore, HydratedSimpleNativeProperty} from "./simple-native-property-api";
3
6
  import {buildDefaultValueFromDefinition} from "./simple-native-property-internal-shared";
4
7
 
5
- export abstract class SNPDataStore implements DataStore<ActualBlockEditProps> {
8
+ export abstract class SNPDataStore implements DataStore {
6
9
  private readonly managedPropertyNames: {[propertyName in string]: true};
7
10
 
11
+ protected readonly blockClientId: string;
12
+ protected readonly blockName: BlockName;
13
+
8
14
  public constructor(
9
- protected explicitBlockEditProps: ActualBlockEditProps,
10
- private attributeCache: Record<string, any>
15
+ explicitBlockEditProps: ActualBlockEditProps,
16
+ private attributeCache: Record<string, any>,
17
+ public readonly id: string
11
18
  ) {
12
19
  this.managedPropertyNames = Object.create(null);
13
- }
14
20
 
15
- get blockEditProps() {
16
- return this.explicitBlockEditProps;
21
+ this.blockClientId = explicitBlockEditProps.clientId;
22
+ this.blockName = explicitBlockEditProps.name;
17
23
  }
18
24
 
19
25
  getValue(attr: string): any {
@@ -31,17 +37,20 @@ export abstract class SNPDataStore implements DataStore<ActualBlockEditProps> {
31
37
  return name in this.managedPropertyNames;
32
38
  }
33
39
 
34
- reattach(explicitBlockEditProps: ActualBlockEditProps, attributeCache: Record<string, any>) {
35
- if (this.explicitBlockEditProps !== explicitBlockEditProps) { // If the block's properties haven't changed, there's no reason to clear the attribute cache
36
- this.explicitBlockEditProps = explicitBlockEditProps;
37
- this.attributeCache = attributeCache;
38
- }
39
- return this;
40
+ reattach(attributeCache: Record<string, any>) {
41
+ this.attributeCache = attributeCache;
40
42
  }
41
43
 
42
44
  protected abstract getAttribute(name: string): any;
43
45
  protected abstract setAttribute(name: string, value: any): void;
44
46
 
47
+ protected getRawBlockAttributes() {
48
+ return select(blockEditorStore).getBlockAttributes(this.blockClientId) ?? {};
49
+ }
50
+ protected setRawBlockAttributes(attributes: Record<string, any>) {
51
+ dispatch(blockEditorStore).updateBlockAttributes!(this.blockClientId, attributes);
52
+ }
53
+
45
54
  protected getCachedValue(attr: string) {
46
55
  return this.attributeCache[attr];
47
56
  }
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption,
3
- __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon, PanelBody, TabPanel
3
+ __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon
4
4
  } from "@wordpress/components";
5
5
  import {memo, useCallback, useMemo} from "@wordpress/element";
6
6
  import {__} from "@wordpress/i18n";
7
7
  import * as icons from "@wordpress/icons";
8
8
 
9
- import type {TogglePropertyCSNPConfig} from "../blocks/csnp-api";
10
- import * as plauditIcons from "../lib/plaudit-icons";
11
9
  import type {IconName, OptionalLabel} from "../blocks";
10
+ import type {TogglePropertyCSNPConfig} from "../blocks/csnp-api";
12
11
  import type {CSNPControlComponentProps, NormalSwitch, PlauditIconName, WordPressIconName} from "../blocks/shared-internal-types";
12
+ import * as plauditIcons from "../lib/plaudit-icons";
13
13
 
14
14
  import parse from "html-react-parser";
15
15
 
@@ -26,17 +26,18 @@ export const layeredBlockStylesLogicSelectors = {
26
26
  };
27
27
 
28
28
  export function layeredBlockStylesLogic(state: LayeredBlockStylesLogicState, action: LayeredBlockStylesLogicActions|WordPressMetaActions): typeof state {
29
- if (action.type === "ADD_LAYERED_BLOCK_STYLES") {
30
- return produce(state, (draft: typeof state) => {
31
- const blockLayeredStyles = draft.layeredBlockStyles[action.blockName] ?? (draft.layeredBlockStyles[action.blockName] = {});
32
- for (const layer of action.properties) {
33
- blockLayeredStyles[layer.name] = layer;
34
- }
35
- });
36
- } else if (action.type === "SET_LAYERED_BLOCK_STYLES") {
37
- return produce(state, (draft: typeof state) => {
38
- draft.layeredBlockStyles[action.blockName] = action.properties;
39
- });
29
+ switch (action.type) {
30
+ case "ADD_LAYERED_BLOCK_STYLES":
31
+ return produce(state, (draft: typeof state) => {
32
+ const blockLayeredStyles = draft.layeredBlockStyles[action.blockName] ?? (draft.layeredBlockStyles[action.blockName] = {});
33
+ for (const layer of action.properties) {
34
+ blockLayeredStyles[layer.name] = layer;
35
+ }
36
+ });
37
+ case "SET_LAYERED_BLOCK_STYLES":
38
+ return produce(state, (draft: typeof state) => {
39
+ draft.layeredBlockStyles[action.blockName] = action.properties;
40
+ });
40
41
  }
41
42
  return state;
42
43
  }
@@ -80,7 +80,7 @@ export function snpLogic(state: SNPLogicState, action: SNPLogicActions|WordPress
80
80
  });
81
81
  case "ADD_OR_UPDATE_EXTRA_PROP_TRANSFORM":
82
82
  return produce(state, (draft: typeof state) => {
83
- const blockTransforms = draft.extraPropTransforms[action.blockName] ?? (draft.extraPropTransforms[action.blockName] = {});
83
+ const blockTransforms = (draft.extraPropTransforms[action.blockName] ??= {});
84
84
  if (blockTransforms[action.propPath]) {
85
85
  blockTransforms[action.propPath]!.styleProperty = action.extraPropTransform.styleProperty;
86
86
  } else {
@@ -106,7 +106,7 @@ export function snpLogic(state: SNPLogicState, action: SNPLogicActions|WordPress
106
106
  }
107
107
 
108
108
  export function addProperties(block: BlockName, properties: PropertiesParameter, simpleNativePanelsAndTabs: SNPLogicState['desiccatedProperties']) {
109
- const panels = (simpleNativePanelsAndTabs[block] ?? (simpleNativePanelsAndTabs[block] = []));
109
+ const panels = (simpleNativePanelsAndTabs[block] ??= []);
110
110
  if ('title' in properties) {
111
111
  panels.push(properties);
112
112
  return;