@wordpress/block-editor 15.10.1-next.79a2f3cdd.0 → 15.10.1-next.v.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/build/components/block-bindings/attribute-control.cjs +1 -1
- package/build/components/block-bindings/attribute-control.cjs.map +1 -1
- package/build/components/block-bindings/source-fields-list.cjs +1 -1
- package/build/components/block-bindings/source-fields-list.cjs.map +1 -1
- package/build/components/block-edit/context.cjs +5 -5
- package/build/components/block-edit/context.cjs.map +1 -1
- package/build/components/block-list/block.cjs +24 -12
- package/build/components/block-list/block.cjs.map +3 -3
- package/build/components/block-list/use-block-props/index.cjs +8 -2
- package/build/components/block-list/use-block-props/index.cjs.map +2 -2
- package/build/components/block-tools/index.cjs +82 -70
- package/build/components/block-tools/index.cjs.map +2 -2
- package/build/components/block-visibility/block-visibility-info.cjs +0 -59
- package/build/components/block-visibility/block-visibility-info.cjs.map +3 -3
- package/build/components/block-visibility/constants.cjs +54 -0
- package/build/components/block-visibility/constants.cjs.map +7 -0
- package/build/components/block-visibility/index.cjs +15 -4
- package/build/components/block-visibility/index.cjs.map +3 -3
- package/build/components/block-visibility/modal.cjs +397 -0
- package/build/components/block-visibility/modal.cjs.map +7 -0
- package/build/components/block-visibility/toolbar.cjs +1 -1
- package/build/components/block-visibility/toolbar.cjs.map +2 -2
- package/build/components/block-visibility/use-block-visibility.cjs +65 -0
- package/build/components/block-visibility/use-block-visibility.cjs.map +7 -0
- package/build/components/block-visibility/utils.cjs +81 -0
- package/build/components/block-visibility/utils.cjs.map +7 -0
- package/build/components/block-visibility/viewport-menu-item.cjs +61 -0
- package/build/components/block-visibility/viewport-menu-item.cjs.map +7 -0
- package/build/components/block-visibility/viewport-toolbar.cjs +89 -0
- package/build/components/block-visibility/viewport-toolbar.cjs.map +7 -0
- package/build/components/collab/block-comment-icon-slot.cjs +1 -1
- package/build/components/collab/block-comment-icon-slot.cjs.map +1 -1
- package/build/components/collab/block-comment-icon-toolbar-slot.cjs +1 -1
- package/build/components/collab/block-comment-icon-toolbar-slot.cjs.map +1 -1
- package/build/components/inner-blocks/use-inner-block-template-sync.cjs +1 -1
- package/build/components/inner-blocks/use-inner-block-template-sync.cjs.map +1 -1
- package/build/components/inserter/menu.cjs +6 -2
- package/build/components/inserter/menu.cjs.map +2 -2
- package/build/components/inspector-controls/groups.cjs +1 -1
- package/build/components/inspector-controls/groups.cjs.map +1 -1
- package/build/components/inspector-controls-tabs/content-tab.cjs +1 -1
- package/build/components/inspector-controls-tabs/content-tab.cjs.map +2 -2
- package/build/components/list-view/block-select-button.cjs +2 -2
- package/build/components/list-view/block-select-button.cjs.map +2 -2
- package/build/components/list-view/block.cjs +39 -22
- package/build/components/list-view/block.cjs.map +2 -2
- package/build/components/list-view/index.cjs +11 -6
- package/build/components/list-view/index.cjs.map +2 -2
- package/build/components/list-view/utils.cjs +24 -17
- package/build/components/list-view/utils.cjs.map +2 -2
- package/build/components/rich-text/event-listeners/input-rules.cjs +13 -1
- package/build/components/rich-text/event-listeners/input-rules.cjs.map +2 -2
- package/build/components/rich-text/format-edit.cjs +1 -1
- package/build/components/rich-text/format-edit.cjs.map +1 -1
- package/build/components/rich-text/index.cjs +2 -2
- package/build/components/rich-text/index.cjs.map +2 -2
- package/build/components/url-input/index.cjs +2 -0
- package/build/components/url-input/index.cjs.map +2 -2
- package/build/components/use-block-commands/index.cjs +1 -1
- package/build/components/use-block-commands/index.cjs.map +2 -2
- package/build/components/writing-flow/utils.cjs +1 -1
- package/build/components/writing-flow/utils.cjs.map +1 -1
- package/build/hooks/block-fields/index.cjs +76 -167
- package/build/hooks/block-fields/index.cjs.map +2 -2
- package/build/hooks/block-fields/link/index.cjs +13 -23
- package/build/hooks/block-fields/link/index.cjs.map +2 -2
- package/build/hooks/block-fields/media/index.cjs +32 -58
- package/build/hooks/block-fields/media/index.cjs.map +2 -2
- package/build/hooks/block-fields/rich-text/index.cjs +1 -5
- package/build/hooks/block-fields/rich-text/index.cjs.map +2 -2
- package/build/hooks/cross-origin-isolation.cjs +102 -0
- package/build/hooks/cross-origin-isolation.cjs.map +7 -0
- package/build/hooks/fit-text.cjs +1 -1
- package/build/hooks/fit-text.cjs.map +1 -1
- package/build/hooks/index.cjs +1 -0
- package/build/hooks/index.cjs.map +2 -2
- package/build/layouts/flex.cjs +6 -2
- package/build/layouts/flex.cjs.map +2 -2
- package/build/store/private-keys.cjs +10 -10
- package/build/store/private-keys.cjs.map +1 -1
- package/build/store/private-selectors.cjs +33 -1
- package/build/store/private-selectors.cjs.map +3 -3
- package/build/store/reducer.cjs +1 -1
- package/build/store/reducer.cjs.map +1 -1
- package/build/store/selectors.cjs +7 -8
- package/build/store/selectors.cjs.map +2 -2
- package/build/store/utils.cjs +1 -1
- package/build/store/utils.cjs.map +1 -1
- package/build-module/components/block-bindings/attribute-control.mjs +1 -1
- package/build-module/components/block-bindings/attribute-control.mjs.map +1 -1
- package/build-module/components/block-bindings/source-fields-list.mjs +1 -1
- package/build-module/components/block-bindings/source-fields-list.mjs.map +1 -1
- package/build-module/components/block-edit/context.mjs +5 -5
- package/build-module/components/block-edit/context.mjs.map +1 -1
- package/build-module/components/block-list/block.mjs +24 -12
- package/build-module/components/block-list/block.mjs.map +3 -3
- package/build-module/components/block-list/use-block-props/index.mjs +8 -2
- package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
- package/build-module/components/block-tools/index.mjs +85 -73
- package/build-module/components/block-tools/index.mjs.map +2 -2
- package/build-module/components/block-visibility/block-visibility-info.mjs +0 -59
- package/build-module/components/block-visibility/block-visibility-info.mjs.map +3 -3
- package/build-module/components/block-visibility/constants.mjs +28 -0
- package/build-module/components/block-visibility/constants.mjs.map +7 -0
- package/build-module/components/block-visibility/index.mjs +13 -4
- package/build-module/components/block-visibility/index.mjs.map +2 -2
- package/build-module/components/block-visibility/modal.mjs +384 -0
- package/build-module/components/block-visibility/modal.mjs.map +7 -0
- package/build-module/components/block-visibility/toolbar.mjs +1 -1
- package/build-module/components/block-visibility/toolbar.mjs.map +2 -2
- package/build-module/components/block-visibility/use-block-visibility.mjs +44 -0
- package/build-module/components/block-visibility/use-block-visibility.mjs.map +7 -0
- package/build-module/components/block-visibility/utils.mjs +55 -0
- package/build-module/components/block-visibility/utils.mjs.map +7 -0
- package/build-module/components/block-visibility/viewport-menu-item.mjs +40 -0
- package/build-module/components/block-visibility/viewport-menu-item.mjs.map +7 -0
- package/build-module/components/block-visibility/viewport-toolbar.mjs +68 -0
- package/build-module/components/block-visibility/viewport-toolbar.mjs.map +7 -0
- package/build-module/components/collab/block-comment-icon-slot.mjs +1 -1
- package/build-module/components/collab/block-comment-icon-slot.mjs.map +1 -1
- package/build-module/components/collab/block-comment-icon-toolbar-slot.mjs +1 -1
- package/build-module/components/collab/block-comment-icon-toolbar-slot.mjs.map +1 -1
- package/build-module/components/inner-blocks/use-inner-block-template-sync.mjs +1 -1
- package/build-module/components/inner-blocks/use-inner-block-template-sync.mjs.map +1 -1
- package/build-module/components/inserter/menu.mjs +6 -2
- package/build-module/components/inserter/menu.mjs.map +2 -2
- package/build-module/components/inspector-controls/groups.mjs +1 -1
- package/build-module/components/inspector-controls/groups.mjs.map +1 -1
- package/build-module/components/inspector-controls-tabs/content-tab.mjs +1 -1
- package/build-module/components/inspector-controls-tabs/content-tab.mjs.map +2 -2
- package/build-module/components/list-view/block-select-button.mjs +2 -2
- package/build-module/components/list-view/block-select-button.mjs.map +2 -2
- package/build-module/components/list-view/block.mjs +39 -22
- package/build-module/components/list-view/block.mjs.map +2 -2
- package/build-module/components/list-view/index.mjs +11 -7
- package/build-module/components/list-view/index.mjs.map +2 -2
- package/build-module/components/list-view/utils.mjs +24 -17
- package/build-module/components/list-view/utils.mjs.map +2 -2
- package/build-module/components/rich-text/event-listeners/input-rules.mjs +13 -1
- package/build-module/components/rich-text/event-listeners/input-rules.mjs.map +2 -2
- package/build-module/components/rich-text/format-edit.mjs +1 -1
- package/build-module/components/rich-text/format-edit.mjs.map +1 -1
- package/build-module/components/rich-text/index.mjs +2 -2
- package/build-module/components/rich-text/index.mjs.map +2 -2
- package/build-module/components/url-input/index.mjs +2 -0
- package/build-module/components/url-input/index.mjs.map +2 -2
- package/build-module/components/use-block-commands/index.mjs +1 -1
- package/build-module/components/use-block-commands/index.mjs.map +2 -2
- package/build-module/components/writing-flow/utils.mjs +1 -1
- package/build-module/components/writing-flow/utils.mjs.map +1 -1
- package/build-module/hooks/block-fields/index.mjs +76 -167
- package/build-module/hooks/block-fields/index.mjs.map +2 -2
- package/build-module/hooks/block-fields/link/index.mjs +13 -23
- package/build-module/hooks/block-fields/link/index.mjs.map +2 -2
- package/build-module/hooks/block-fields/media/index.mjs +32 -58
- package/build-module/hooks/block-fields/media/index.mjs.map +2 -2
- package/build-module/hooks/block-fields/rich-text/index.mjs +1 -5
- package/build-module/hooks/block-fields/rich-text/index.mjs.map +2 -2
- package/build-module/hooks/cross-origin-isolation.mjs +100 -0
- package/build-module/hooks/cross-origin-isolation.mjs.map +7 -0
- package/build-module/hooks/fit-text.mjs +1 -1
- package/build-module/hooks/fit-text.mjs.map +1 -1
- package/build-module/hooks/index.mjs +1 -0
- package/build-module/hooks/index.mjs.map +2 -2
- package/build-module/layouts/flex.mjs +6 -2
- package/build-module/layouts/flex.mjs.map +2 -2
- package/build-module/store/private-keys.mjs +10 -10
- package/build-module/store/private-keys.mjs.map +1 -1
- package/build-module/store/private-selectors.mjs +34 -1
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs +1 -1
- package/build-module/store/reducer.mjs.map +1 -1
- package/build-module/store/selectors.mjs +7 -8
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-module/store/utils.mjs +1 -1
- package/build-module/store/utils.mjs.map +1 -1
- package/build-style/content-rtl.css +4 -1
- package/build-style/content.css +4 -1
- package/build-style/style-rtl.css +54 -1
- package/build-style/style.css +54 -1
- package/package.json +39 -39
- package/src/components/block-bindings/attribute-control.js +1 -1
- package/src/components/block-bindings/source-fields-list.js +1 -1
- package/src/components/block-list/block.js +23 -9
- package/src/components/block-list/content.scss +4 -1
- package/src/components/block-list/use-block-props/index.js +10 -2
- package/src/components/block-toolbar/style.scss +0 -1
- package/src/components/block-tools/index.js +45 -33
- package/src/components/block-tools/style.scss +10 -0
- package/src/components/block-visibility/block-visibility-info.js +0 -1
- package/src/components/block-visibility/constants.js +33 -0
- package/src/components/block-visibility/index.js +21 -2
- package/src/components/block-visibility/modal.js +358 -0
- package/src/components/block-visibility/style.scss +58 -0
- package/src/components/block-visibility/test/use-block-visibility.js +316 -0
- package/src/components/block-visibility/test/utils.js +266 -0
- package/src/components/block-visibility/toolbar.js +1 -1
- package/src/components/block-visibility/use-block-visibility.js +70 -0
- package/src/components/block-visibility/utils.js +95 -0
- package/src/components/block-visibility/viewport-menu-item.js +42 -0
- package/src/components/block-visibility/viewport-toolbar.js +88 -0
- package/src/components/inner-blocks/use-inner-block-template-sync.js +1 -1
- package/src/components/inserter/menu.js +6 -2
- package/src/components/inspector-controls-tabs/content-tab.js +0 -1
- package/src/components/list-view/block-select-button.js +2 -2
- package/src/components/list-view/block.js +47 -25
- package/src/components/list-view/index.js +15 -11
- package/src/components/list-view/utils.js +31 -23
- package/src/components/rich-text/event-listeners/input-rules.js +17 -0
- package/src/components/rich-text/index.js +1 -1
- package/src/components/url-input/index.js +2 -0
- package/src/components/use-block-commands/index.js +4 -3
- package/src/hooks/block-fields/index.js +104 -225
- package/src/hooks/block-fields/link/index.js +13 -39
- package/src/hooks/block-fields/media/index.js +31 -90
- package/src/hooks/block-fields/rich-text/index.js +1 -5
- package/src/hooks/block-fields/styles.scss +2 -0
- package/src/hooks/cross-origin-isolation.js +143 -0
- package/src/hooks/fit-text.js +1 -1
- package/src/hooks/index.js +1 -0
- package/src/layouts/flex.js +8 -3
- package/src/layouts/test/flex.js +53 -0
- package/src/store/private-selectors.js +64 -1
- package/src/store/reducer.js +1 -1
- package/src/store/selectors.js +7 -9
- package/src/store/test/private-selectors.js +80 -0
- package/src/style.scss +1 -0
- package/src/components/block-visibility/styles.scss +0 -10
|
@@ -29,6 +29,7 @@ var import_components = require("@wordpress/components");
|
|
|
29
29
|
var import_compose = require("@wordpress/compose");
|
|
30
30
|
var import_dataviews = require("@wordpress/dataviews");
|
|
31
31
|
var import_element = require("@wordpress/element");
|
|
32
|
+
var import_i18n = require("@wordpress/i18n");
|
|
32
33
|
var import_lock_unlock = require("../../lock-unlock.cjs");
|
|
33
34
|
var import_block_icon = __toESM(require("../../components/block-icon/index.cjs"));
|
|
34
35
|
var import_use_block_display_title = __toESM(require("../../components/block-title/use-block-display-title.cjs"));
|
|
@@ -46,171 +47,85 @@ var CONTROLS = {
|
|
|
46
47
|
media: import_media.default,
|
|
47
48
|
link: import_link.default
|
|
48
49
|
};
|
|
49
|
-
function createConfiguredControl(config) {
|
|
50
|
-
const { control, ...controlConfig } = config;
|
|
51
|
-
const ControlComponent = CONTROLS[control];
|
|
50
|
+
function createConfiguredControl(ControlComponent, type, config) {
|
|
52
51
|
if (!ControlComponent) {
|
|
53
|
-
throw new Error(`Control type "${
|
|
52
|
+
throw new Error(`Control type "${type}" not found`);
|
|
54
53
|
}
|
|
55
54
|
return function ConfiguredControl(props) {
|
|
56
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlComponent, { ...props, config
|
|
55
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlComponent, { ...props, config });
|
|
57
56
|
};
|
|
58
57
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
poster: "",
|
|
67
|
-
featuredImage: false,
|
|
68
|
-
link: ""
|
|
69
|
-
};
|
|
70
|
-
const result = {};
|
|
71
|
-
if (fieldDef?.mapping) {
|
|
72
|
-
Object.keys(fieldDef.mapping).forEach((key) => {
|
|
73
|
-
result[key] = value?.[key] ?? defaults[key] ?? "";
|
|
74
|
-
});
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
Object.keys(defaults).forEach((key) => {
|
|
78
|
-
result[key] = value?.[key] ?? defaults[key];
|
|
79
|
-
});
|
|
80
|
-
return result;
|
|
81
|
-
}
|
|
82
|
-
function denormalizeMediaValue(value, fieldDef) {
|
|
83
|
-
if (!fieldDef.mapping) {
|
|
84
|
-
return value;
|
|
85
|
-
}
|
|
86
|
-
const result = {};
|
|
87
|
-
Object.entries(fieldDef.mapping).forEach(([key]) => {
|
|
88
|
-
if (key in value) {
|
|
89
|
-
result[key] = value[key];
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
function normalizeLinkValue(value, fieldDef) {
|
|
95
|
-
const defaults = {
|
|
96
|
-
url: "",
|
|
97
|
-
rel: "",
|
|
98
|
-
linkTarget: "",
|
|
99
|
-
destination: ""
|
|
100
|
-
};
|
|
101
|
-
const result = {};
|
|
102
|
-
if (fieldDef?.mapping) {
|
|
103
|
-
Object.keys(fieldDef.mapping).forEach((key) => {
|
|
104
|
-
result[key] = value?.[key] ?? defaults[key] ?? "";
|
|
105
|
-
});
|
|
106
|
-
return result;
|
|
107
|
-
}
|
|
108
|
-
Object.keys(defaults).forEach((key) => {
|
|
109
|
-
result[key] = value?.[key] ?? defaults[key];
|
|
110
|
-
});
|
|
111
|
-
return result;
|
|
112
|
-
}
|
|
113
|
-
function denormalizeLinkValue(value, fieldDef) {
|
|
114
|
-
if (!fieldDef.mapping) {
|
|
115
|
-
return value;
|
|
116
|
-
}
|
|
117
|
-
const result = {};
|
|
118
|
-
Object.entries(fieldDef.mapping).forEach(([key]) => {
|
|
119
|
-
if (key in value) {
|
|
120
|
-
result[key] = value[key];
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
return result;
|
|
124
|
-
}
|
|
125
|
-
function BlockFields({ clientId, blockType, attributes, setAttributes }) {
|
|
58
|
+
function BlockFields({
|
|
59
|
+
clientId,
|
|
60
|
+
blockType,
|
|
61
|
+
attributes,
|
|
62
|
+
setAttributes,
|
|
63
|
+
isCollapsed = false
|
|
64
|
+
}) {
|
|
126
65
|
const blockTitle = (0, import_use_block_display_title.default)({
|
|
127
66
|
clientId,
|
|
128
67
|
context: "list-view"
|
|
129
68
|
});
|
|
130
69
|
const blockInformation = (0, import_use_block_display_information.default)(clientId);
|
|
131
70
|
const blockTypeFields = blockType?.[fieldsKey];
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
71
|
+
const computedForm = (0, import_element.useMemo)(() => {
|
|
72
|
+
if (!isCollapsed) {
|
|
73
|
+
return blockType?.[formKey];
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
...blockType?.[formKey],
|
|
77
|
+
fields: [blockType?.[formKey]?.fields?.[0]]
|
|
78
|
+
};
|
|
79
|
+
}, [blockType, isCollapsed]);
|
|
80
|
+
const [form, setForm] = (0, import_element.useState)(computedForm);
|
|
135
81
|
const dataFormFields = (0, import_element.useMemo)(() => {
|
|
136
82
|
if (!blockTypeFields?.length) {
|
|
137
83
|
return [];
|
|
138
84
|
}
|
|
139
85
|
return blockTypeFields.map((fieldDef) => {
|
|
140
|
-
const ControlComponent = CONTROLS[fieldDef.type];
|
|
141
|
-
const defaultValues = {};
|
|
142
|
-
if (fieldDef.mapping && blockType?.attributes) {
|
|
143
|
-
Object.entries(fieldDef.mapping).forEach(
|
|
144
|
-
([key, attrKey]) => {
|
|
145
|
-
defaultValues[key] = blockType.attributes[attrKey]?.defaultValue ?? void 0;
|
|
146
|
-
}
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
86
|
const field = {
|
|
150
87
|
id: fieldDef.id,
|
|
151
88
|
label: fieldDef.label,
|
|
152
|
-
type: fieldDef.type
|
|
89
|
+
type: fieldDef.type
|
|
153
90
|
// Use the field's type; DataForm will use built-in or custom Edit
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
([key, attrKey]) => {
|
|
162
|
-
mappedValue[key] = item[attrKey];
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
if (fieldDef.type === "media") {
|
|
166
|
-
return normalizeMediaValue(mappedValue, fieldDef);
|
|
167
|
-
}
|
|
168
|
-
if (fieldDef.type === "link") {
|
|
169
|
-
return normalizeLinkValue(mappedValue, fieldDef);
|
|
91
|
+
};
|
|
92
|
+
if (fieldDef.mapping) {
|
|
93
|
+
field.getValue = ({ item }) => {
|
|
94
|
+
const mappedValue = {};
|
|
95
|
+
Object.entries(fieldDef.mapping).forEach(
|
|
96
|
+
([key, attrKey]) => {
|
|
97
|
+
mappedValue[key] = item[attrKey];
|
|
170
98
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
denormalizedValue = denormalizeMediaValue(
|
|
180
|
-
value,
|
|
181
|
-
fieldDef
|
|
182
|
-
);
|
|
183
|
-
} else if (fieldDef.type === "link") {
|
|
184
|
-
denormalizedValue = denormalizeLinkValue(
|
|
185
|
-
value,
|
|
186
|
-
fieldDef
|
|
187
|
-
);
|
|
99
|
+
);
|
|
100
|
+
return mappedValue;
|
|
101
|
+
};
|
|
102
|
+
field.setValue = ({ value }) => {
|
|
103
|
+
const attributeUpdates = {};
|
|
104
|
+
Object.entries(fieldDef.mapping).forEach(
|
|
105
|
+
([key, attrKey]) => {
|
|
106
|
+
attributeUpdates[attrKey] = value[key];
|
|
188
107
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
} else {
|
|
195
|
-
updates[attrKey] = item[attrKey];
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
);
|
|
199
|
-
return updates;
|
|
200
|
-
}
|
|
201
|
-
return { [fieldDef.id]: value };
|
|
202
|
-
}
|
|
203
|
-
};
|
|
108
|
+
);
|
|
109
|
+
return attributeUpdates;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const ControlComponent = CONTROLS[fieldDef.type];
|
|
204
113
|
if (ControlComponent) {
|
|
205
|
-
field.Edit = createConfiguredControl(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
114
|
+
field.Edit = createConfiguredControl(
|
|
115
|
+
ControlComponent,
|
|
116
|
+
fieldDef.type,
|
|
117
|
+
{
|
|
118
|
+
clientId,
|
|
119
|
+
fieldDef
|
|
120
|
+
}
|
|
121
|
+
);
|
|
210
122
|
}
|
|
211
123
|
return field;
|
|
212
124
|
});
|
|
213
|
-
}, [blockTypeFields,
|
|
125
|
+
}, [blockTypeFields, clientId]);
|
|
126
|
+
if (!blockTypeFields?.length) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
214
129
|
const handleToggleField = (fieldId) => {
|
|
215
130
|
setForm((prev) => {
|
|
216
131
|
if (prev.fields?.includes(fieldId)) {
|
|
@@ -225,34 +140,27 @@ function BlockFields({ clientId, blockType, attributes, setAttributes }) {
|
|
|
225
140
|
};
|
|
226
141
|
});
|
|
227
142
|
};
|
|
228
|
-
if (!blockTypeFields?.length) {
|
|
229
|
-
return null;
|
|
230
|
-
}
|
|
231
143
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "block-editor-block-fields__container", children: [
|
|
232
144
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "block-editor-block-fields__header", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalHStack, { spacing: 1, children: [
|
|
233
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
import_components.__experimentalTruncate,
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
visibleFields: form.fields,
|
|
253
|
-
onToggleField: handleToggleField
|
|
254
|
-
}
|
|
255
|
-
)
|
|
145
|
+
isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
146
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
147
|
+
import_block_icon.default,
|
|
148
|
+
{
|
|
149
|
+
className: "block-editor-block-fields__header-icon",
|
|
150
|
+
icon: blockInformation?.icon
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "block-editor-block-fields__header-title", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalTruncate, { numberOfLines: 1, children: blockTitle }) }),
|
|
154
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
155
|
+
import_fields_dropdown_menu.default,
|
|
156
|
+
{
|
|
157
|
+
fields: dataFormFields,
|
|
158
|
+
visibleFields: form.fields,
|
|
159
|
+
onToggleField: handleToggleField
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
] }),
|
|
163
|
+
!isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "block-editor-block-fields__header-title", children: (0, import_i18n.__)("Content") })
|
|
256
164
|
] }) }),
|
|
257
165
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
258
166
|
import_dataviews.DataForm,
|
|
@@ -274,7 +182,7 @@ var withBlockFields = (0, import_compose.createHigherOrderComponent)(
|
|
|
274
182
|
blockEditingMode,
|
|
275
183
|
isSelected
|
|
276
184
|
} = (0, import_element.useContext)(import_private_block_context.PrivateBlockContext);
|
|
277
|
-
const shouldShowBlockFields = window?.
|
|
185
|
+
const shouldShowBlockFields = window?.__experimentalContentOnlyInspectorFields;
|
|
278
186
|
const blockTypeFields = blockType?.[fieldsKey];
|
|
279
187
|
if (!shouldShowBlockFields || !blockTypeFields?.length) {
|
|
280
188
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlockEdit, { ...props }, "edit");
|
|
@@ -291,7 +199,8 @@ var withBlockFields = (0, import_compose.createHigherOrderComponent)(
|
|
|
291
199
|
BlockFields,
|
|
292
200
|
{
|
|
293
201
|
...props,
|
|
294
|
-
blockType
|
|
202
|
+
blockType,
|
|
203
|
+
isCollapsed: true
|
|
295
204
|
}
|
|
296
205
|
)
|
|
297
206
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/hooks/block-fields/index.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { addFilter } from '@wordpress/hooks';\nimport { privateApis as blocksPrivateApis } from '@wordpress/blocks';\nimport {\n\t__experimentalHStack as HStack,\n\t__experimentalTruncate as Truncate,\n} from '@wordpress/components';\nimport { createHigherOrderComponent } from '@wordpress/compose';\nimport { DataForm } from '@wordpress/dataviews';\nimport { useContext, useState, useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport BlockIcon from '../../components/block-icon';\nimport useBlockDisplayTitle from '../../components/block-title/use-block-display-title';\nimport useBlockDisplayInformation from '../../components/use-block-display-information';\nconst { fieldsKey, formKey } = unlock( blocksPrivateApis );\nimport FieldsDropdownMenu from './fields-dropdown-menu';\nimport { PrivateBlockContext } from '../../components/block-list/private-block-context';\nimport { PrivateInspectorControlsFill } from '../../components/inspector-controls/fill';\n\n// controls\nimport RichText from './rich-text';\nimport Media from './media';\nimport Link from './link';\n\nconst CONTROLS = {\n\trichtext: RichText,\n\tmedia: Media,\n\tlink: Link,\n};\n\n/**\n * Creates a configured control component that wraps a custom control\n * and passes configuration as props.\n *\n * @param {Object} config - The control configuration\n * @param {string} config.control - The control type (key in CONTROLS map)\n * @return {Function} A wrapped control component\n */\nfunction createConfiguredControl( config ) {\n\tconst { control, ...controlConfig } = config;\n\tconst ControlComponent = CONTROLS[ control ];\n\n\tif ( ! ControlComponent ) {\n\t\tthrow new Error( `Control type \"${ control }\" not found` );\n\t}\n\n\treturn function ConfiguredControl( props ) {\n\t\treturn <ControlComponent { ...props } config={ controlConfig } />;\n\t};\n}\n\n/**\n * Normalize a media value to a canonical structure.\n * Only includes properties that are present in the field's mapping (if provided).\n *\n * @param {Object} value - The mapped value from the block attributes (with canonical keys)\n * @param {Object} fieldDef - Optional field definition containing the mapping\n * @return {Object} Normalized media value with canonical properties\n */\nfunction normalizeMediaValue( value, fieldDef ) {\n\tconst defaults = {\n\t\tid: null,\n\t\turl: '',\n\t\tcaption: '',\n\t\talt: '',\n\t\ttype: 'image',\n\t\tposter: '',\n\t\tfeaturedImage: false,\n\t\tlink: '',\n\t};\n\n\tconst result = {};\n\n\t// If there's a mapping, only include properties that are in it\n\tif ( fieldDef?.mapping ) {\n\t\tObject.keys( fieldDef.mapping ).forEach( ( key ) => {\n\t\t\tresult[ key ] = value?.[ key ] ?? defaults[ key ] ?? '';\n\t\t} );\n\t\treturn result;\n\t}\n\n\t// Without mapping, include all default properties\n\tObject.keys( defaults ).forEach( ( key ) => {\n\t\tresult[ key ] = value?.[ key ] ?? defaults[ key ];\n\t} );\n\treturn result;\n}\n\n/**\n * Denormalize a media value from canonical structure back to mapped keys.\n * Only includes properties that are present in the field's mapping.\n *\n * @param {Object} value - The normalized media value\n * @param {Object} fieldDef - The field definition containing the mapping\n * @return {Object} Value with only mapped properties\n */\nfunction denormalizeMediaValue( value, fieldDef ) {\n\tif ( ! fieldDef.mapping ) {\n\t\treturn value;\n\t}\n\n\tconst result = {};\n\tObject.entries( fieldDef.mapping ).forEach( ( [ key ] ) => {\n\t\tif ( key in value ) {\n\t\t\tresult[ key ] = value[ key ];\n\t\t}\n\t} );\n\treturn result;\n}\n\n/**\n * Normalize a link value to a canonical structure.\n * Only includes properties that are present in the field's mapping (if provided).\n *\n * @param {Object} value - The mapped value from the block attributes (with canonical keys)\n * @param {Object} fieldDef - Optional field definition containing the mapping\n * @return {Object} Normalized link value with canonical properties\n */\nfunction normalizeLinkValue( value, fieldDef ) {\n\tconst defaults = {\n\t\turl: '',\n\t\trel: '',\n\t\tlinkTarget: '',\n\t\tdestination: '',\n\t};\n\n\tconst result = {};\n\n\t// If there's a mapping, only include properties that are in it\n\tif ( fieldDef?.mapping ) {\n\t\tObject.keys( fieldDef.mapping ).forEach( ( key ) => {\n\t\t\tresult[ key ] = value?.[ key ] ?? defaults[ key ] ?? '';\n\t\t} );\n\t\treturn result;\n\t}\n\n\t// Without mapping, include all default properties\n\tObject.keys( defaults ).forEach( ( key ) => {\n\t\tresult[ key ] = value?.[ key ] ?? defaults[ key ];\n\t} );\n\treturn result;\n}\n\n/**\n * Denormalize a link value from canonical structure back to mapped keys.\n * Only includes properties that are present in the field's mapping.\n *\n * @param {Object} value - The normalized link value\n * @param {Object} fieldDef - The field definition containing the mapping\n * @return {Object} Value with only mapped properties\n */\nfunction denormalizeLinkValue( value, fieldDef ) {\n\tif ( ! fieldDef.mapping ) {\n\t\treturn value;\n\t}\n\n\tconst result = {};\n\tObject.entries( fieldDef.mapping ).forEach( ( [ key ] ) => {\n\t\tif ( key in value ) {\n\t\t\tresult[ key ] = value[ key ];\n\t\t}\n\t} );\n\treturn result;\n}\n\nfunction BlockFields( { clientId, blockType, attributes, setAttributes } ) {\n\tconst blockTitle = useBlockDisplayTitle( {\n\t\tclientId,\n\t\tcontext: 'list-view',\n\t} );\n\tconst blockInformation = useBlockDisplayInformation( clientId );\n\n\tconst blockTypeFields = blockType?.[ fieldsKey ];\n\n\tconst [ form, setForm ] = useState( () => {\n\t\treturn blockType?.[ formKey ];\n\t} );\n\n\t// Build DataForm fields with proper structure\n\tconst dataFormFields = useMemo( () => {\n\t\tif ( ! blockTypeFields?.length ) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn blockTypeFields.map( ( fieldDef ) => {\n\t\t\tconst ControlComponent = CONTROLS[ fieldDef.type ];\n\n\t\t\tconst defaultValues = {};\n\t\t\tif ( fieldDef.mapping && blockType?.attributes ) {\n\t\t\t\tObject.entries( fieldDef.mapping ).forEach(\n\t\t\t\t\t( [ key, attrKey ] ) => {\n\t\t\t\t\t\tdefaultValues[ key ] =\n\t\t\t\t\t\t\tblockType.attributes[ attrKey ]?.defaultValue ??\n\t\t\t\t\t\t\tundefined;\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst field = {\n\t\t\t\tid: fieldDef.id,\n\t\t\t\tlabel: fieldDef.label,\n\t\t\t\ttype: fieldDef.type, // Use the field's type; DataForm will use built-in or custom Edit\n\t\t\t\tconfig: { ...fieldDef.args, defaultValues },\n\t\t\t\thideLabelFromVision: fieldDef.id === 'content',\n\t\t\t\t// getValue and setValue handle the mapping to block attributes\n\t\t\t\tgetValue: ( { item } ) => {\n\t\t\t\t\tif ( fieldDef.mapping ) {\n\t\t\t\t\t\t// Extract mapped properties from the block attributes\n\t\t\t\t\t\tconst mappedValue = {};\n\t\t\t\t\t\tObject.entries( fieldDef.mapping ).forEach(\n\t\t\t\t\t\t\t( [ key, attrKey ] ) => {\n\t\t\t\t\t\t\t\tmappedValue[ key ] = item[ attrKey ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Normalize to canonical structure based on field type\n\t\t\t\t\t\tif ( fieldDef.type === 'media' ) {\n\t\t\t\t\t\t\treturn normalizeMediaValue( mappedValue, fieldDef );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( fieldDef.type === 'link' ) {\n\t\t\t\t\t\t\treturn normalizeLinkValue( mappedValue, fieldDef );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// For other types, return as-is\n\t\t\t\t\t\treturn mappedValue;\n\t\t\t\t\t}\n\t\t\t\t\t// For simple id-based fields, use the id as the attribute key\n\t\t\t\t\treturn item[ fieldDef.id ];\n\t\t\t\t},\n\t\t\t\tsetValue: ( { item, value } ) => {\n\t\t\t\t\tif ( fieldDef.mapping ) {\n\t\t\t\t\t\t// Denormalize from canonical structure back to mapped keys\n\t\t\t\t\t\tlet denormalizedValue = value;\n\t\t\t\t\t\tif ( fieldDef.type === 'media' ) {\n\t\t\t\t\t\t\tdenormalizedValue = denormalizeMediaValue(\n\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\tfieldDef\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else if ( fieldDef.type === 'link' ) {\n\t\t\t\t\t\t\tdenormalizedValue = denormalizeLinkValue(\n\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\tfieldDef\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Build an object with all mapped attributes\n\t\t\t\t\t\tconst updates = {};\n\t\t\t\t\t\tObject.entries( fieldDef.mapping ).forEach(\n\t\t\t\t\t\t\t( [ key, attrKey ] ) => {\n\t\t\t\t\t\t\t\t// If key is explicitly in value, use it (even if undefined to allow clearing)\n\t\t\t\t\t\t\t\t// Otherwise, preserve the old value\n\t\t\t\t\t\t\t\tif ( key in denormalizedValue ) {\n\t\t\t\t\t\t\t\t\tupdates[ attrKey ] =\n\t\t\t\t\t\t\t\t\t\tdenormalizedValue[ key ];\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tupdates[ attrKey ] = item[ attrKey ];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn updates;\n\t\t\t\t\t}\n\t\t\t\t\t// For simple id-based fields, use the id as the attribute key\n\t\t\t\t\treturn { [ fieldDef.id ]: value };\n\t\t\t\t},\n\t\t\t};\n\n\t\t\t// Only add custom Edit component if one exists for this type\n\t\t\tif ( ControlComponent ) {\n\t\t\t\t// Use EditConfig pattern: Edit is an object with control type and config props\n\t\t\t\tfield.Edit = createConfiguredControl( {\n\t\t\t\t\tcontrol: fieldDef.type,\n\t\t\t\t\tclientId,\n\t\t\t\t\tfieldDef,\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn field;\n\t\t} );\n\t}, [ blockTypeFields, blockType?.attributes, clientId ] );\n\n\tconst handleToggleField = ( fieldId ) => {\n\t\tsetForm( ( prev ) => {\n\t\t\tif ( prev.fields?.includes( fieldId ) ) {\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tfields: prev.fields.filter( ( id ) => id !== fieldId ),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tfields: [ ...( prev.fields || [] ), fieldId ],\n\t\t\t};\n\t\t} );\n\t};\n\n\tif ( ! blockTypeFields?.length ) {\n\t\t// TODO - we might still want to show a placeholder for blocks with no fields.\n\t\t// for example, a way to select the block.\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className=\"block-editor-block-fields__container\">\n\t\t\t<div className=\"block-editor-block-fields__header\">\n\t\t\t\t<HStack spacing={ 1 }>\n\t\t\t\t\t<BlockIcon\n\t\t\t\t\t\tclassName=\"block-editor-block-fields__header-icon\"\n\t\t\t\t\t\ticon={ blockInformation?.icon }\n\t\t\t\t\t/>\n\t\t\t\t\t<Truncate\n\t\t\t\t\t\tclassName=\"block-editor-block-fields__header-title\"\n\t\t\t\t\t\tnumberOfLines={ 1 }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ blockTitle }\n\t\t\t\t\t</Truncate>\n\t\t\t\t\t<FieldsDropdownMenu\n\t\t\t\t\t\tfields={ dataFormFields }\n\t\t\t\t\t\tvisibleFields={ form.fields }\n\t\t\t\t\t\tonToggleField={ handleToggleField }\n\t\t\t\t\t/>\n\t\t\t\t</HStack>\n\t\t\t</div>\n\t\t\t<DataForm\n\t\t\t\tdata={ attributes }\n\t\t\t\tfields={ dataFormFields }\n\t\t\t\tform={ form }\n\t\t\t\tonChange={ setAttributes }\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nconst withBlockFields = createHigherOrderComponent(\n\t( BlockEdit ) => ( props ) => {\n\t\tconst {\n\t\t\tblockType,\n\t\t\tisSelectionWithinCurrentSection,\n\t\t\tisSectionBlock,\n\t\t\tblockEditingMode,\n\t\t\tisSelected,\n\t\t} = useContext( PrivateBlockContext );\n\n\t\tconst shouldShowBlockFields =\n\t\t\twindow?.__experimentalContentOnlyPatternInsertion &&\n\t\t\twindow?.__experimentalContentOnlyInspectorFields;\n\t\tconst blockTypeFields = blockType?.[ fieldsKey ];\n\n\t\tif ( ! shouldShowBlockFields || ! blockTypeFields?.length ) {\n\t\t\treturn <BlockEdit key=\"edit\" { ...props } />;\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<BlockEdit key=\"edit\" { ...props } />\n\t\t\t\t{\n\t\t\t\t\t// Display the controls of all inner blocks for section/pattern editing.\n\t\t\t\t\tisSelectionWithinCurrentSection &&\n\t\t\t\t\t\t( isSectionBlock ||\n\t\t\t\t\t\t\tblockEditingMode === 'contentOnly' ) && (\n\t\t\t\t\t\t\t<PrivateInspectorControlsFill\n\t\t\t\t\t\t\t\tgroup=\"content\"\n\t\t\t\t\t\t\t\tforceDisplayControls\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<BlockFields\n\t\t\t\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\t\t\t\tblockType={ blockType }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</PrivateInspectorControlsFill>\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\t{ ! isSelectionWithinCurrentSection && isSelected && (\n\t\t\t\t\t<PrivateInspectorControlsFill group=\"content\">\n\t\t\t\t\t\t<BlockFields { ...props } blockType={ blockType } />\n\t\t\t\t\t</PrivateInspectorControlsFill>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n);\n\naddFilter(\n\t'editor.BlockEdit',\n\t'core/content-only-controls/block-fields',\n\twithBlockFields\n);\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAGA,mBAA0B;AAC1B,oBAAiD;AACjD,wBAGO;AACP,qBAA2C;AAC3C,uBAAyB;AACzB,qBAA8C;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { addFilter } from '@wordpress/hooks';\nimport { privateApis as blocksPrivateApis } from '@wordpress/blocks';\nimport {\n\t__experimentalHStack as HStack,\n\t__experimentalTruncate as Truncate,\n} from '@wordpress/components';\nimport { createHigherOrderComponent } from '@wordpress/compose';\nimport { DataForm } from '@wordpress/dataviews';\nimport { useContext, useState, useMemo } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport BlockIcon from '../../components/block-icon';\nimport useBlockDisplayTitle from '../../components/block-title/use-block-display-title';\nimport useBlockDisplayInformation from '../../components/use-block-display-information';\nconst { fieldsKey, formKey } = unlock( blocksPrivateApis );\nimport FieldsDropdownMenu from './fields-dropdown-menu';\nimport { PrivateBlockContext } from '../../components/block-list/private-block-context';\nimport { PrivateInspectorControlsFill } from '../../components/inspector-controls/fill';\n\n// controls\nimport RichText from './rich-text';\nimport Media from './media';\nimport Link from './link';\n\nconst CONTROLS = {\n\trichtext: RichText,\n\tmedia: Media,\n\tlink: Link,\n};\n\n/**\n * Creates a configured control component that wraps a custom control\n * and passes configuration as props.\n *\n * @param {Component} ControlComponent The React component for the control.\n * @param {string} type The type of control.\n * @param {Object} config The control configuration passed as a prop.\n *\n * @return {Function} A wrapped control component\n */\nfunction createConfiguredControl( ControlComponent, type, config ) {\n\tif ( ! ControlComponent ) {\n\t\tthrow new Error( `Control type \"${ type }\" not found` );\n\t}\n\n\treturn function ConfiguredControl( props ) {\n\t\treturn <ControlComponent { ...props } config={ config } />;\n\t};\n}\n\n/**\n * Component that renders a DataForm for a single block's attributes\n * @param {Object} props\n * @param {string} props.clientId The clientId of the block.\n * @param {Object} props.blockType The blockType definition.\n * @param {Object} props.attributes The block's attribute values.\n * @param {Function} props.setAttributes Action to set the block's attributes.\n * @param {boolean} props.isCollapsed Whether the DataForm is rendered as 'collapsed' with only the first field\n * displayed by default. When collapsed a dropdown is displayed to allow\n * displaying additional fields. The block's title is displayed as the title.\n * The collapsed mode is often used when multiple BlockForms are shown together.\n */\nfunction BlockFields( {\n\tclientId,\n\tblockType,\n\tattributes,\n\tsetAttributes,\n\tisCollapsed = false,\n} ) {\n\tconst blockTitle = useBlockDisplayTitle( {\n\t\tclientId,\n\t\tcontext: 'list-view',\n\t} );\n\tconst blockInformation = useBlockDisplayInformation( clientId );\n\n\tconst blockTypeFields = blockType?.[ fieldsKey ];\n\n\tconst computedForm = useMemo( () => {\n\t\tif ( ! isCollapsed ) {\n\t\t\treturn blockType?.[ formKey ];\n\t\t}\n\n\t\t// For a collapsed form only show the first field by default.\n\t\treturn {\n\t\t\t...blockType?.[ formKey ],\n\t\t\tfields: [ blockType?.[ formKey ]?.fields?.[ 0 ] ],\n\t\t};\n\t}, [ blockType, isCollapsed ] );\n\n\tconst [ form, setForm ] = useState( computedForm );\n\n\t// Build DataForm fields with proper structure\n\tconst dataFormFields = useMemo( () => {\n\t\tif ( ! blockTypeFields?.length ) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn blockTypeFields.map( ( fieldDef ) => {\n\t\t\tconst field = {\n\t\t\t\tid: fieldDef.id,\n\t\t\t\tlabel: fieldDef.label,\n\t\t\t\ttype: fieldDef.type, // Use the field's type; DataForm will use built-in or custom Edit\n\t\t\t};\n\n\t\t\t// If the field defines a `mapping`, then custom `getValue` and `setValue`\n\t\t\t// implementations are provided.\n\t\t\t// These functions map from the inconsistent attribute keys found on blocks\n\t\t\t// to consistent keys that the field can use internally (and back again).\n\t\t\t// When `mapping` isn't provided, we can use the field API's default\n\t\t\t// implementation of these functions.\n\t\t\tif ( fieldDef.mapping ) {\n\t\t\t\tfield.getValue = ( { item } ) => {\n\t\t\t\t\t// Extract mapped properties from the block attributes\n\t\t\t\t\tconst mappedValue = {};\n\t\t\t\t\tObject.entries( fieldDef.mapping ).forEach(\n\t\t\t\t\t\t( [ key, attrKey ] ) => {\n\t\t\t\t\t\t\tmappedValue[ key ] = item[ attrKey ];\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\treturn mappedValue;\n\t\t\t\t};\n\t\t\t\tfield.setValue = ( { value } ) => {\n\t\t\t\t\tconst attributeUpdates = {};\n\t\t\t\t\tObject.entries( fieldDef.mapping ).forEach(\n\t\t\t\t\t\t( [ key, attrKey ] ) => {\n\t\t\t\t\t\t\tattributeUpdates[ attrKey ] = value[ key ];\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\treturn attributeUpdates;\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Only add custom Edit component if one exists for this type\n\t\t\tconst ControlComponent = CONTROLS[ fieldDef.type ];\n\t\t\tif ( ControlComponent ) {\n\t\t\t\t// Use EditConfig pattern: Edit is an object with control type and config props\n\t\t\t\tfield.Edit = createConfiguredControl(\n\t\t\t\t\tControlComponent,\n\t\t\t\t\tfieldDef.type,\n\t\t\t\t\t{\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t\tfieldDef,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn field;\n\t\t} );\n\t}, [ blockTypeFields, clientId ] );\n\n\tif ( ! blockTypeFields?.length ) {\n\t\t// TODO - we might still want to show a placeholder for blocks with no fields.\n\t\t// for example, a way to select the block.\n\t\treturn null;\n\t}\n\n\tconst handleToggleField = ( fieldId ) => {\n\t\tsetForm( ( prev ) => {\n\t\t\tif ( prev.fields?.includes( fieldId ) ) {\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tfields: prev.fields.filter( ( id ) => id !== fieldId ),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tfields: [ ...( prev.fields || [] ), fieldId ],\n\t\t\t};\n\t\t} );\n\t};\n\n\treturn (\n\t\t<div className=\"block-editor-block-fields__container\">\n\t\t\t<div className=\"block-editor-block-fields__header\">\n\t\t\t\t<HStack spacing={ 1 }>\n\t\t\t\t\t{ isCollapsed && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<BlockIcon\n\t\t\t\t\t\t\t\tclassName=\"block-editor-block-fields__header-icon\"\n\t\t\t\t\t\t\t\ticon={ blockInformation?.icon }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<h2 className=\"block-editor-block-fields__header-title\">\n\t\t\t\t\t\t\t\t<Truncate numberOfLines={ 1 }>\n\t\t\t\t\t\t\t\t\t{ blockTitle }\n\t\t\t\t\t\t\t\t</Truncate>\n\t\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t\t<FieldsDropdownMenu\n\t\t\t\t\t\t\t\tfields={ dataFormFields }\n\t\t\t\t\t\t\t\tvisibleFields={ form.fields }\n\t\t\t\t\t\t\t\tonToggleField={ handleToggleField }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</>\n\t\t\t\t\t) }\n\t\t\t\t\t{ ! isCollapsed && (\n\t\t\t\t\t\t<h2 className=\"block-editor-block-fields__header-title\">\n\t\t\t\t\t\t\t{ __( 'Content' ) }\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t) }\n\t\t\t\t</HStack>\n\t\t\t</div>\n\t\t\t<DataForm\n\t\t\t\tdata={ attributes }\n\t\t\t\tfields={ dataFormFields }\n\t\t\t\tform={ form }\n\t\t\t\tonChange={ setAttributes }\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nconst withBlockFields = createHigherOrderComponent(\n\t( BlockEdit ) => ( props ) => {\n\t\tconst {\n\t\t\tblockType,\n\t\t\tisSelectionWithinCurrentSection,\n\t\t\tisSectionBlock,\n\t\t\tblockEditingMode,\n\t\t\tisSelected,\n\t\t} = useContext( PrivateBlockContext );\n\n\t\tconst shouldShowBlockFields =\n\t\t\twindow?.__experimentalContentOnlyInspectorFields;\n\t\tconst blockTypeFields = blockType?.[ fieldsKey ];\n\n\t\tif ( ! shouldShowBlockFields || ! blockTypeFields?.length ) {\n\t\t\treturn <BlockEdit key=\"edit\" { ...props } />;\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<BlockEdit key=\"edit\" { ...props } />\n\t\t\t\t{\n\t\t\t\t\t// Display the controls of all inner blocks for section/pattern editing.\n\t\t\t\t\tisSelectionWithinCurrentSection &&\n\t\t\t\t\t\t( isSectionBlock ||\n\t\t\t\t\t\t\tblockEditingMode === 'contentOnly' ) && (\n\t\t\t\t\t\t\t<PrivateInspectorControlsFill\n\t\t\t\t\t\t\t\tgroup=\"content\"\n\t\t\t\t\t\t\t\tforceDisplayControls\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<BlockFields\n\t\t\t\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\t\t\t\tblockType={ blockType }\n\t\t\t\t\t\t\t\t\tisCollapsed\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</PrivateInspectorControlsFill>\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\t{ ! isSelectionWithinCurrentSection && isSelected && (\n\t\t\t\t\t<PrivateInspectorControlsFill group=\"content\">\n\t\t\t\t\t\t<BlockFields { ...props } blockType={ blockType } />\n\t\t\t\t\t</PrivateInspectorControlsFill>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n);\n\naddFilter(\n\t'editor.BlockEdit',\n\t'core/content-only-controls/block-fields',\n\twithBlockFields\n);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["blocksPrivateApis", "RichText", "Media", "Link", "useBlockDisplayTitle", "useBlockDisplayInformation", "HStack", "BlockIcon", "Truncate", "FieldsDropdownMenu"]
|
|
7
7
|
}
|
|
@@ -81,10 +81,6 @@ function Link({ data, field, onChange, config = {} }) {
|
|
|
81
81
|
isControl: true
|
|
82
82
|
});
|
|
83
83
|
const { fieldDef } = config;
|
|
84
|
-
const updateAttributes = (newValue) => {
|
|
85
|
-
const mappedChanges = field.setValue({ item: data, value: newValue });
|
|
86
|
-
onChange(mappedChanges);
|
|
87
|
-
};
|
|
88
84
|
const value = field.getValue({ item: data });
|
|
89
85
|
const url = value?.url;
|
|
90
86
|
const rel = value?.rel || "";
|
|
@@ -148,34 +144,28 @@ function Link({ data, field, onChange, config = {} }) {
|
|
|
148
144
|
rel,
|
|
149
145
|
...newValues
|
|
150
146
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
} else if (key === "rel") {
|
|
158
|
-
updateValue[key] = updatedAttrs.rel;
|
|
159
|
-
} else if (key === "target" || key === "linkTarget") {
|
|
160
|
-
updateValue[key] = updatedAttrs.linkTarget;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
updateAttributes(updateValue);
|
|
147
|
+
onChange(
|
|
148
|
+
field.setValue({
|
|
149
|
+
item: data,
|
|
150
|
+
value: updatedAttrs
|
|
151
|
+
})
|
|
152
|
+
);
|
|
166
153
|
},
|
|
167
154
|
onRemove: () => {
|
|
168
155
|
const removeValue = {};
|
|
169
156
|
if (fieldDef?.mapping) {
|
|
170
157
|
Object.keys(fieldDef.mapping).forEach(
|
|
171
158
|
(key) => {
|
|
172
|
-
|
|
173
|
-
removeValue[key] = void 0;
|
|
174
|
-
}
|
|
159
|
+
removeValue[key] = void 0;
|
|
175
160
|
}
|
|
176
161
|
);
|
|
177
162
|
}
|
|
178
|
-
|
|
163
|
+
onChange(
|
|
164
|
+
field.setValue({
|
|
165
|
+
item: data,
|
|
166
|
+
value: removeValue
|
|
167
|
+
})
|
|
168
|
+
);
|
|
179
169
|
}
|
|
180
170
|
}
|
|
181
171
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/hooks/block-fields/link/index.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tIcon,\n\t__experimentalGrid as Grid,\n\tPopover,\n} from '@wordpress/components';\nimport { useMemo, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { link } from '@wordpress/icons';\nimport { prependHTTP } from '@wordpress/url';\n\n/**\n * Internal dependencies\n */\nimport LinkControl from '../../../components/link-control';\nimport { useInspectorPopoverPlacement } from '../use-inspector-popover-placement';\n\nexport const NEW_TAB_REL = 'noreferrer noopener';\nexport const NEW_TAB_TARGET = '_blank';\nexport const NOFOLLOW_REL = 'nofollow';\n\n/**\n * Updates the link attributes.\n *\n * @param {Object} attributes The current block attributes.\n * @param {string} attributes.rel The current link rel attribute.\n * @param {string} attributes.url The current link url.\n * @param {boolean} attributes.opensInNewTab Whether the link should open in a new window.\n * @param {boolean} attributes.nofollow Whether the link should be marked as nofollow.\n */\nexport function getUpdatedLinkAttributes( {\n\trel = '',\n\turl = '',\n\topensInNewTab,\n\tnofollow,\n} ) {\n\tlet newLinkTarget;\n\t// Since `rel` is editable attribute, we need to check for existing values and proceed accordingly.\n\tlet updatedRel = rel;\n\n\tif ( opensInNewTab ) {\n\t\tnewLinkTarget = NEW_TAB_TARGET;\n\t\tupdatedRel = updatedRel?.includes( NEW_TAB_REL )\n\t\t\t? updatedRel\n\t\t\t: updatedRel + ` ${ NEW_TAB_REL }`;\n\t} else {\n\t\tconst relRegex = new RegExp( `\\\\b${ NEW_TAB_REL }\\\\s*`, 'g' );\n\t\tupdatedRel = updatedRel?.replace( relRegex, '' ).trim();\n\t}\n\n\tif ( nofollow ) {\n\t\tupdatedRel = updatedRel?.includes( NOFOLLOW_REL )\n\t\t\t? updatedRel\n\t\t\t: ( updatedRel + ` ${ NOFOLLOW_REL }` ).trim();\n\t} else {\n\t\tconst relRegex = new RegExp( `\\\\b${ NOFOLLOW_REL }\\\\s*`, 'g' );\n\t\tupdatedRel = updatedRel?.replace( relRegex, '' ).trim();\n\t}\n\n\treturn {\n\t\turl: prependHTTP( url ),\n\t\tlinkTarget: newLinkTarget,\n\t\trel: updatedRel || undefined,\n\t};\n}\n\nexport default function Link( { data, field, onChange, config = {} } ) {\n\tconst [ isLinkControlOpen, setIsLinkControlOpen ] = useState( false );\n\tconst { popoverProps } = useInspectorPopoverPlacement( {\n\t\tisControl: true,\n\t} );\n\tconst { fieldDef } = config;\n\tconst
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,wBAKO;AACP,qBAAkC;AAClC,kBAAmB;AACnB,mBAAqB;AACrB,iBAA4B;AAK5B,0BAAwB;AACxB,6CAA6C;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tIcon,\n\t__experimentalGrid as Grid,\n\tPopover,\n} from '@wordpress/components';\nimport { useMemo, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { link } from '@wordpress/icons';\nimport { prependHTTP } from '@wordpress/url';\n\n/**\n * Internal dependencies\n */\nimport LinkControl from '../../../components/link-control';\nimport { useInspectorPopoverPlacement } from '../use-inspector-popover-placement';\n\nexport const NEW_TAB_REL = 'noreferrer noopener';\nexport const NEW_TAB_TARGET = '_blank';\nexport const NOFOLLOW_REL = 'nofollow';\n\n/**\n * Updates the link attributes.\n *\n * @param {Object} attributes The current block attributes.\n * @param {string} attributes.rel The current link rel attribute.\n * @param {string} attributes.url The current link url.\n * @param {boolean} attributes.opensInNewTab Whether the link should open in a new window.\n * @param {boolean} attributes.nofollow Whether the link should be marked as nofollow.\n */\nexport function getUpdatedLinkAttributes( {\n\trel = '',\n\turl = '',\n\topensInNewTab,\n\tnofollow,\n} ) {\n\tlet newLinkTarget;\n\t// Since `rel` is editable attribute, we need to check for existing values and proceed accordingly.\n\tlet updatedRel = rel;\n\n\tif ( opensInNewTab ) {\n\t\tnewLinkTarget = NEW_TAB_TARGET;\n\t\tupdatedRel = updatedRel?.includes( NEW_TAB_REL )\n\t\t\t? updatedRel\n\t\t\t: updatedRel + ` ${ NEW_TAB_REL }`;\n\t} else {\n\t\tconst relRegex = new RegExp( `\\\\b${ NEW_TAB_REL }\\\\s*`, 'g' );\n\t\tupdatedRel = updatedRel?.replace( relRegex, '' ).trim();\n\t}\n\n\tif ( nofollow ) {\n\t\tupdatedRel = updatedRel?.includes( NOFOLLOW_REL )\n\t\t\t? updatedRel\n\t\t\t: ( updatedRel + ` ${ NOFOLLOW_REL }` ).trim();\n\t} else {\n\t\tconst relRegex = new RegExp( `\\\\b${ NOFOLLOW_REL }\\\\s*`, 'g' );\n\t\tupdatedRel = updatedRel?.replace( relRegex, '' ).trim();\n\t}\n\n\treturn {\n\t\turl: prependHTTP( url ),\n\t\tlinkTarget: newLinkTarget,\n\t\trel: updatedRel || undefined,\n\t};\n}\n\nexport default function Link( { data, field, onChange, config = {} } ) {\n\tconst [ isLinkControlOpen, setIsLinkControlOpen ] = useState( false );\n\tconst { popoverProps } = useInspectorPopoverPlacement( {\n\t\tisControl: true,\n\t} );\n\tconst { fieldDef } = config;\n\tconst value = field.getValue( { item: data } );\n\tconst url = value?.url;\n\tconst rel = value?.rel || '';\n\tconst target = value?.linkTarget;\n\n\tconst opensInNewTab = target === NEW_TAB_TARGET;\n\tconst nofollow = rel === NOFOLLOW_REL;\n\n\t// Memoize link value to avoid overriding the LinkControl's internal state.\n\t// This is a temporary fix. See https://github.com/WordPress/gutenberg/issues/51256.\n\tconst linkValue = useMemo(\n\t\t() => ( { url, opensInNewTab, nofollow } ),\n\t\t[ url, opensInNewTab, nofollow ]\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<Button\n\t\t\t\t__next40pxDefaultSize\n\t\t\t\tclassName=\"block-editor-content-only-controls__link\"\n\t\t\t\tonClick={ () => {\n\t\t\t\t\tsetIsLinkControlOpen( true );\n\t\t\t\t} }\n\t\t\t>\n\t\t\t\t<Grid\n\t\t\t\t\trowGap={ 0 }\n\t\t\t\t\tcolumnGap={ 8 }\n\t\t\t\t\ttemplateColumns=\"24px 1fr\"\n\t\t\t\t\tclassName=\"block-editor-content-only-controls__link-row\"\n\t\t\t\t>\n\t\t\t\t\t{ url && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<Icon icon={ link } size={ 24 } />\n\t\t\t\t\t\t\t<span className=\"block-editor-content-only-controls__link-title\">\n\t\t\t\t\t\t\t\t{ url }\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</>\n\t\t\t\t\t) }\n\t\t\t\t\t{ ! url && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\ticon={ link }\n\t\t\t\t\t\t\t\tsize={ 24 }\n\t\t\t\t\t\t\t\tstyle={ { opacity: 0.3 } }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span className=\"block-editor-content-only-controls__link-title\">\n\t\t\t\t\t\t\t\t{ __( 'Link' ) }\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</>\n\t\t\t\t\t) }\n\t\t\t\t</Grid>\n\t\t\t</Button>\n\t\t\t{ isLinkControlOpen && (\n\t\t\t\t<Popover\n\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\tsetIsLinkControlOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t\t{ ...( popoverProps ?? {} ) }\n\t\t\t\t>\n\t\t\t\t\t<LinkControl\n\t\t\t\t\t\tvalue={ linkValue }\n\t\t\t\t\t\tonChange={ ( newValues ) => {\n\t\t\t\t\t\t\tconst updatedAttrs = getUpdatedLinkAttributes( {\n\t\t\t\t\t\t\t\trel,\n\t\t\t\t\t\t\t\t...newValues,\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\tonChange(\n\t\t\t\t\t\t\t\tfield.setValue( {\n\t\t\t\t\t\t\t\t\titem: data,\n\t\t\t\t\t\t\t\t\tvalue: updatedAttrs,\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tonRemove={ () => {\n\t\t\t\t\t\t\t// Remove all link-related properties based on what's in the mapping\n\t\t\t\t\t\t\tconst removeValue = {};\n\n\t\t\t\t\t\t\tif ( fieldDef?.mapping ) {\n\t\t\t\t\t\t\t\tObject.keys( fieldDef.mapping ).forEach(\n\t\t\t\t\t\t\t\t\t( key ) => {\n\t\t\t\t\t\t\t\t\t\tremoveValue[ key ] = undefined;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tonChange(\n\t\t\t\t\t\t\t\tfield.setValue( {\n\t\t\t\t\t\t\t\t\titem: data,\n\t\t\t\t\t\t\t\t\tvalue: removeValue,\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t</Popover>\n\t\t\t) }\n\t\t</>\n\t);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Grid", "LinkControl"]
|
|
7
7
|
}
|
|
@@ -43,9 +43,9 @@ var import_use_inspector_popover_placement = require("../use-inspector-popover-p
|
|
|
43
43
|
var import_private_keys = require("../../../store/private-keys.cjs");
|
|
44
44
|
var import_store = require("../../../store/index.cjs");
|
|
45
45
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
46
|
-
function MediaThumbnail({ data, field, attachment }) {
|
|
47
|
-
const
|
|
48
|
-
const { allowedTypes = [], multiple = false } =
|
|
46
|
+
function MediaThumbnail({ data, field, attachment, config }) {
|
|
47
|
+
const { fieldDef } = config;
|
|
48
|
+
const { allowedTypes = [], multiple = false } = fieldDef.args || {};
|
|
49
49
|
if (multiple) {
|
|
50
50
|
return "todo multiple";
|
|
51
51
|
}
|
|
@@ -63,7 +63,7 @@ function MediaThumbnail({ data, field, attachment }) {
|
|
|
63
63
|
if (allowedTypes.length === 1) {
|
|
64
64
|
const value = field.getValue({ item: data });
|
|
65
65
|
const url = value?.url;
|
|
66
|
-
if (url) {
|
|
66
|
+
if (allowedTypes[0] === "image" && url) {
|
|
67
67
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "block-editor-content-only-controls__media-thumbnail", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { alt: "", width: 24, height: 24, src: url }) });
|
|
68
68
|
}
|
|
69
69
|
let icon;
|
|
@@ -87,15 +87,8 @@ function Media({ data, field, onChange, config = {} }) {
|
|
|
87
87
|
isControl: true
|
|
88
88
|
});
|
|
89
89
|
const value = field.getValue({ item: data });
|
|
90
|
-
const { allowedTypes = [], multiple = false } = field.config || {};
|
|
91
90
|
const { fieldDef } = config;
|
|
92
|
-
const
|
|
93
|
-
const mappedChanges = field.setValue({
|
|
94
|
-
item: data,
|
|
95
|
-
value: newFieldValue
|
|
96
|
-
});
|
|
97
|
-
onChange(mappedChanges);
|
|
98
|
-
};
|
|
91
|
+
const { allowedTypes = [], multiple = false } = fieldDef.args || {};
|
|
99
92
|
const hasFeaturedImageSupport = fieldDef?.mapping && "featuredImage" in fieldDef.mapping;
|
|
100
93
|
const id = value?.id;
|
|
101
94
|
const url = value?.url;
|
|
@@ -141,64 +134,44 @@ function Media({ data, field, onChange, config = {} }) {
|
|
|
141
134
|
const resetValue = {};
|
|
142
135
|
if (fieldDef?.mapping) {
|
|
143
136
|
Object.keys(fieldDef.mapping).forEach((key) => {
|
|
144
|
-
|
|
145
|
-
resetValue[key] = void 0;
|
|
146
|
-
} else if (key === "caption" || key === "alt") {
|
|
147
|
-
resetValue[key] = "";
|
|
148
|
-
}
|
|
137
|
+
resetValue[key] = void 0;
|
|
149
138
|
});
|
|
150
139
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
140
|
+
onChange(
|
|
141
|
+
field.setValue({
|
|
142
|
+
item: data,
|
|
143
|
+
value: resetValue
|
|
144
|
+
})
|
|
145
|
+
);
|
|
155
146
|
},
|
|
156
147
|
...hasFeaturedImageSupport && {
|
|
157
148
|
useFeaturedImage: !!value?.featuredImage,
|
|
158
149
|
onToggleFeaturedImage: () => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
150
|
+
onChange(
|
|
151
|
+
field.setValue({
|
|
152
|
+
item: data,
|
|
153
|
+
value: {
|
|
154
|
+
featuredImage: !value?.featuredImage
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
);
|
|
163
158
|
}
|
|
164
159
|
},
|
|
165
160
|
onSelect: (selectedMedia) => {
|
|
166
161
|
if (selectedMedia.id && selectedMedia.url) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
} else if (selectedMedia.mime_type.startsWith("audio/")) {
|
|
172
|
-
mediaType = "audio";
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
const newValue = {};
|
|
176
|
-
if (fieldDef?.mapping) {
|
|
177
|
-
Object.keys(fieldDef.mapping).forEach(
|
|
178
|
-
(key) => {
|
|
179
|
-
if (key === "id") {
|
|
180
|
-
newValue[key] = selectedMedia.id;
|
|
181
|
-
} else if (key === "src" || key === "url") {
|
|
182
|
-
newValue[key] = selectedMedia.url;
|
|
183
|
-
} else if (key === "type") {
|
|
184
|
-
newValue[key] = mediaType;
|
|
185
|
-
} else if (key === "link" && selectedMedia.link) {
|
|
186
|
-
newValue[key] = selectedMedia.link;
|
|
187
|
-
} else if (key === "caption" && !value?.caption && selectedMedia.caption) {
|
|
188
|
-
newValue[key] = selectedMedia.caption;
|
|
189
|
-
} else if (key === "alt" && !value?.alt && selectedMedia.alt) {
|
|
190
|
-
newValue[key] = selectedMedia.alt;
|
|
191
|
-
} else if (key === "poster" && selectedMedia.poster) {
|
|
192
|
-
newValue[key] = selectedMedia.poster;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
);
|
|
196
|
-
}
|
|
162
|
+
const newValue = {
|
|
163
|
+
...selectedMedia,
|
|
164
|
+
mediaType: selectedMedia.media_type
|
|
165
|
+
};
|
|
197
166
|
if (hasFeaturedImageSupport) {
|
|
198
167
|
newValue.featuredImage = false;
|
|
199
168
|
}
|
|
200
|
-
|
|
201
|
-
|
|
169
|
+
onChange(
|
|
170
|
+
field.setValue({
|
|
171
|
+
item: data,
|
|
172
|
+
value: newValue
|
|
173
|
+
})
|
|
174
|
+
);
|
|
202
175
|
}
|
|
203
176
|
},
|
|
204
177
|
renderToggle: (buttonProps) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -221,7 +194,8 @@ function Media({ data, field, onChange, config = {} }) {
|
|
|
221
194
|
{
|
|
222
195
|
attachment,
|
|
223
196
|
field,
|
|
224
|
-
data
|
|
197
|
+
data,
|
|
198
|
+
config
|
|
225
199
|
}
|
|
226
200
|
),
|
|
227
201
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|