@plaudit/gutenberg-api-extensions 2.84.4 → 2.85.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/CHANGELOG.md +9 -0
- package/dist/blocks/common-native-property-constructors.js +12 -0
- package/dist/blocks/common-native-property-constructors.js.map +1 -1
- package/dist/blocks/csnp-api.d.ts +4 -3
- package/dist/blocks/csnp-api.js +3 -2
- package/dist/blocks/csnp-api.js.map +1 -1
- package/dist/blocks/data-controller/reducer.js +3 -2
- package/dist/blocks/data-controller/reducer.js.map +1 -1
- package/dist/blocks/data-controller/trigger-handlers.js +3 -3
- package/dist/blocks/data-controller/trigger-handlers.js.map +1 -1
- package/dist/blocks/data-controller/utils.d.ts +5 -2
- package/dist/blocks/data-controller/utils.js +25 -2
- package/dist/blocks/data-controller/utils.js.map +1 -1
- package/dist/blocks/data-controller.d.ts +1 -1
- package/dist/blocks/data-controller.js +1 -1
- package/dist/blocks/data-controller.js.map +1 -1
- package/dist/controls/FileControl.d.ts +9 -0
- package/dist/controls/FileControl.js +27 -0
- package/dist/controls/FileControl.js.map +1 -0
- package/dist/controls/index.d.ts +1 -0
- package/dist/controls/index.js +1 -0
- package/dist/controls/index.js.map +1 -1
- package/package.json +5 -5
- package/simple-native-properties.md +122 -89
- package/src/blocks/common-native-property-constructors.tsx +13 -1
- package/src/blocks/csnp-api.ts +11 -8
- package/src/blocks/data-controller/reducer.ts +4 -3
- package/src/blocks/data-controller/trigger-handlers.ts +5 -4
- package/src/blocks/data-controller/utils.ts +27 -4
- package/src/blocks/data-controller.ts +2 -2
- package/src/controls/FileControl.tsx +48 -0
- package/src/controls/index.ts +1 -0
|
@@ -109,8 +109,8 @@ export function descendIntoDCNodeChild(current: DCNode|undefined, path: RawPath,
|
|
|
109
109
|
return current;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
export function getDataStore(property: string, state: Draft<DCStoreState>, throwOnError:
|
|
113
|
-
export function getDataStore(property: string, state: Draft<DCStoreState>, throwOnError?: undefined|
|
|
112
|
+
export function getDataStore(property: string, state: Draft<DCStoreState>, throwOnError: true): DataStore;
|
|
113
|
+
export function getDataStore(property: string, state: Draft<DCStoreState>, throwOnError?: undefined|boolean|false): DataStore|undefined;
|
|
114
114
|
export function getDataStore(property: string, state: Draft<DCStoreState>, throwOnError = true): DataStore|undefined {
|
|
115
115
|
let dataStore = state.dataStores.byProperty[property];
|
|
116
116
|
if (dataStore) {
|
|
@@ -127,7 +127,7 @@ export function getDataStore(property: string, state: Draft<DCStoreState>, throw
|
|
|
127
127
|
|
|
128
128
|
export function getOptionalValue(path: NodePath, state: Draft<DCStoreState>) {
|
|
129
129
|
try {
|
|
130
|
-
return walkToNodeInValue(getDataStore(path[0], state).getValue(path[0]), path);
|
|
130
|
+
return walkToNodeInValue(getDataStore(path[0], state, true).getValue(path[0]), path);
|
|
131
131
|
} catch (e) {
|
|
132
132
|
if (e instanceof PathError) {
|
|
133
133
|
return undefined;
|
|
@@ -162,7 +162,7 @@ export function writeValueToBackingDataStoreWithCorrections(path: NodePath, stat
|
|
|
162
162
|
if (rootDCNode === undefined) {
|
|
163
163
|
throw new PathError("Encountered a path pointing to a non-existent root node.", path, 0);
|
|
164
164
|
}
|
|
165
|
-
const dataStore = getDataStore(path[0], state);
|
|
165
|
+
const dataStore = getDataStore(path[0], state, true);
|
|
166
166
|
|
|
167
167
|
// This path both handles scalar values and ensures that the root "value" of Groups and Lists are initialized before writing the actual attribute
|
|
168
168
|
// To avoid accidentally overwriting group data when lazily adding items (i.e., via a ToolsPanel instance), we skip this code path if the group's root value has already been initialized
|
|
@@ -306,6 +306,29 @@ export function recordCloneableDefaultValueForNode<T extends HydratedSimpleNativ
|
|
|
306
306
|
return definition as HydratedSimpleNativeProperty<{uuid: UUID}>;
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
const recordedBackupValues: Record<UUID, any> = {};
|
|
310
|
+
export function recordBackupForNode(node: DCNode, value: any) {
|
|
311
|
+
if (!node.backup) {
|
|
312
|
+
node.backup = crypto.randomUUID();
|
|
313
|
+
}
|
|
314
|
+
recordedBackupValues[node.backup] = value;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function restoreValueFromPotentialBackup(node: DCNode) {
|
|
318
|
+
if (node.backup && node.backup in recordedBackupValues) {
|
|
319
|
+
const res = recordedBackupValues[node.backup];
|
|
320
|
+
delete recordedBackupValues[node.backup];
|
|
321
|
+
return res ?? buildDefaultValueFromDefinition(node.definition);
|
|
322
|
+
}
|
|
323
|
+
return buildDefaultValueFromDefinition(node.definition)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export function removeBackupForNode(node: DCNode) {
|
|
327
|
+
if (node.backup && node.backup in recordedBackupValues) {
|
|
328
|
+
delete recordedBackupValues[node.backup];
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
309
332
|
export function buildDefaultValueFromDefinition(definition: (HydratedSimpleNativeProperty<{uuid: UUID}>)|undefined, requireNonNullValueOnObject = true): any {
|
|
310
333
|
if (definition === undefined) {
|
|
311
334
|
return undefined;
|
|
@@ -15,7 +15,7 @@ import {getDataStore, getOptionalValue, UUID, walkToNode} from "./data-controlle
|
|
|
15
15
|
|
|
16
16
|
type DescendantsWrapper = {[key: string]: DCNode}|DCNode[];
|
|
17
17
|
export type DCNode = {
|
|
18
|
-
backup?:
|
|
18
|
+
backup?: UUID,
|
|
19
19
|
rendered?: boolean,
|
|
20
20
|
condition?: Condition,
|
|
21
21
|
children?: DescendantsWrapper,
|
|
@@ -39,7 +39,7 @@ export function useDataController(blockClientId: string): DataController {
|
|
|
39
39
|
function getDataStoreImpl(property: string, required: true): DataStore;
|
|
40
40
|
function getDataStoreImpl(property: string, required?: undefined|false): DataStore|undefined;
|
|
41
41
|
function getDataStoreImpl(property: string, required?: boolean): DataStore|undefined {
|
|
42
|
-
return
|
|
42
|
+
return getDataStore(property, store.getState(), required);
|
|
43
43
|
}
|
|
44
44
|
const dataController: DataController = {
|
|
45
45
|
getDataStore: getDataStoreImpl,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {MediaUpload, MediaUploadCheck} from "@wordpress/block-editor";
|
|
2
|
+
import {BaseControl, Button, useBaseControlProps} from "@wordpress/components";
|
|
3
|
+
import {store as coreStore} from "@wordpress/core-data";
|
|
4
|
+
import {useSuspenseSelect} from "@wordpress/data";
|
|
5
|
+
import {useCallback} from "@wordpress/element";
|
|
6
|
+
import {__} from "@wordpress/i18n";
|
|
7
|
+
|
|
8
|
+
import type {ReactNode} from "react";
|
|
9
|
+
|
|
10
|
+
export type FileControlProps = {
|
|
11
|
+
label: ReactNode,
|
|
12
|
+
help?: ReactNode,
|
|
13
|
+
onChange: (value?: number) => void,
|
|
14
|
+
value?: number,
|
|
15
|
+
allowedTypes?: string[]
|
|
16
|
+
};
|
|
17
|
+
export function FileControl(props: FileControlProps) {
|
|
18
|
+
const {allowedTypes, help, label, onChange, value} = props;
|
|
19
|
+
const onSelect = useCallback((media: {id: number}) => {
|
|
20
|
+
if (media.id !== value) {
|
|
21
|
+
onChange(media.id);
|
|
22
|
+
}
|
|
23
|
+
}, [onChange, value]);
|
|
24
|
+
|
|
25
|
+
const attachment = useSuspenseSelect(select => value !== undefined ? select(coreStore).getMedia(value) : undefined, [value]);
|
|
26
|
+
const {baseControlProps, controlProps} = useBaseControlProps({label, help});
|
|
27
|
+
return <BaseControl {...baseControlProps}>
|
|
28
|
+
<MediaUploadCheck>
|
|
29
|
+
<MediaUpload
|
|
30
|
+
onSelect={onSelect}
|
|
31
|
+
value={value}
|
|
32
|
+
allowedTypes={allowedTypes}
|
|
33
|
+
render={useCallback(({open}) => {
|
|
34
|
+
if (!attachment?.id) {
|
|
35
|
+
return <div {...controlProps}><Button onClick={open} children={__('Select a File', 'plaudit')}/></div>
|
|
36
|
+
}
|
|
37
|
+
return <div {...controlProps}>
|
|
38
|
+
<p>{__('Selected File', 'plaudit')}: <a href={attachment.source_url} target="_blank" rel="noopener noreferrer">{attachment.title.rendered}</a></p>
|
|
39
|
+
<div className="selected-file-control-buttons">
|
|
40
|
+
<Button onClick={open} variant="secondary" children="Replace File" />
|
|
41
|
+
<Button onClick={() => onChange(undefined)} isDestructive children={__('Remove File', 'plaudit')} />
|
|
42
|
+
</div>
|
|
43
|
+
</div>;
|
|
44
|
+
}, [attachment, onChange, controlProps])}
|
|
45
|
+
/>
|
|
46
|
+
</MediaUploadCheck>
|
|
47
|
+
</BaseControl>;
|
|
48
|
+
}
|
package/src/controls/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./ExtendedTaxonomyPicker";
|
|
|
7
7
|
export * from "./ExtendedTermPicker";
|
|
8
8
|
export * from "./ExtendedTextareaControl";
|
|
9
9
|
export * from "./ExtendedUserPicker";
|
|
10
|
+
export * from "./FileControl";
|
|
10
11
|
export * from "./FullSizeToggleControl";
|
|
11
12
|
export * from "./ImageControl";
|
|
12
13
|
export * from "./InspectorPanel";
|