PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 All 404 releases
← All changes | build/modules/widget-primitives/index.js +209 -14 23.7.1 → trunk View file →
@@ -110,9 +110,87 @@
110 110 };
111 111 });
112 112 }
113 113
114 +// packages/widget-primitives/build-module/icon-resolver/icon-resolver.mjs
115 +var iconResolver;
116 +function registerIconResolver(resolver) {
117 + if (iconResolver) {
118 + return void 0;
119 + }
120 + iconResolver = resolver;
121 + return resolver;
122 +}
123 +async function resolveIcon(reference) {
124 + if (!iconResolver) {
125 + return null;
126 + }
127 + try {
128 + return await iconResolver(reference);
129 + } catch {
130 + return null;
131 + }
132 +}
133 +
114 134 // packages/widget-primitives/build-module/hooks/use-widget-types.mjs
135 +var pendingIcon = (0, import_element2.createElement)("svg", {
136 + viewBox: "0 0 24 24"
137 +});
138 +function withRenderableIcons(actions, holdPending) {
139 + return actions.map(({ icon, ...action }) => {
140 + if ((0, import_element2.isValidElement)(icon)) {
141 + return { ...action, icon };
142 + }
143 + if (holdPending && typeof icon === "string") {
144 + return { ...action, icon: pendingIcon };
145 + }
146 + return action;
147 + });
148 +}
149 +function mergeAttributes(recordAttributes, moduleAttributes) {
150 + if (!recordAttributes) {
151 + return moduleAttributes;
152 + }
153 + if (!moduleAttributes) {
154 + return recordAttributes;
155 + }
156 + const moduleById = new Map(
157 + moduleAttributes.map(
158 + (attribute) => [attribute.id, attribute]
159 + )
160 + );
161 + const recordIds = new Set(
162 + recordAttributes.map((attribute) => attribute.id)
163 + );
164 + return [
165 + ...recordAttributes.map((attribute) => {
166 + const moduleAttribute = moduleById.get(attribute.id);
167 + if (!moduleAttribute?.isValid || !attribute.isValid) {
168 + return { ...moduleAttribute, ...attribute };
169 + }
170 + return {
171 + ...moduleAttribute,
172 + ...attribute,
173 + isValid: { ...moduleAttribute.isValid, ...attribute.isValid }
174 + };
175 + }),
176 + ...moduleAttributes.filter(
177 + (attribute) => !recordIds.has(attribute.id)
178 + )
179 + ];
180 +}
181 +var DEFAULT_API_VERSION = 1;
182 +function recordOverlay(record) {
183 + return {
184 + name: record.name,
185 + renderModule: record.render_module ?? "",
186 + ...record.presentation ? { presentation: record.presentation } : {},
187 + ...record.category ? { category: record.category } : {},
188 + ...record.description ? { description: record.description } : {},
189 + ...record.help ? { help: record.help } : {},
190 + ...record.keywords ? { keywords: record.keywords } : {}
191 + };
192 +}
115 193 function useWidgetTypes(records) {
116 194 const [widgetTypes, setWidgetTypes] = (0, import_element2.useState)([]);
117 195 const [isResolvingWidgetTypes, setIsResolvingWidgetTypes] = (0, import_element2.useState)(true);
118 196 (0, import_element2.useEffect)(() => {
@@ -129,9 +207,28 @@
129 207 setIsResolvingWidgetTypes(true);
130 208 Promise.all(
131 209 records.map(async (record) => {
132 210 if (!record.widget_module) {
133 - return null;
211 + if (!record.render_module) {
212 + return null;
213 + }
214 + return {
215 + apiVersion: DEFAULT_API_VERSION,
216 + title: record.title ?? record.name,
217 + ...record.attributes ? {
218 + attributes: resolveFields(
219 + record.attributes
220 + )
221 + } : {},
222 + ...record.icon ? { icon: pendingIcon } : {},
223 + ...record.actions ? {
224 + actions: withRenderableIcons(
225 + record.actions,
226 + true
227 + )
228 + } : {},
229 + ...recordOverlay(record)
230 + };
134 231 }
135 232 try {
136 233 const module = await import(
137 234 /* webpackIgnore: true */
@@ -140,17 +237,20 @@
140 237 if (!module?.default) {
141 238 return null;
142 239 }
143 240 const metadata = module.default;
241 + const moduleIcon = (0, import_element2.isValidElement)(metadata.icon) ? metadata.icon : void 0;
242 + const icon = moduleIcon ?? (record.icon ? pendingIcon : void 0);
243 + const actions = record.actions ?? metadata.actions;
244 + const attributes = mergeAttributes(
245 + record.attributes,
246 + metadata.attributes
247 + );
144 248 return {
249 + apiVersion: DEFAULT_API_VERSION,
145 250 ...metadata,
146 - ...metadata.attributes ? {
147 - attributes: resolveFields(
148 - metadata.attributes
149 - )
150 - } : {},
151 - name: record.name,
152 - renderModule: record.render_module ?? "",
251 + ...attributes ? { attributes: resolveFields(attributes) } : {},
252 + icon,
153 253 /*
154 254 * `title` is required:
155 255 * - Server-side title wins
156 256 * - Then the module's title
@@ -156,14 +256,15 @@
156 256 * - Then the module's title
157 257 * - Then the record's name as fallback
158 258 */
159 259 title: record.title ?? metadata.title ?? record.name,
160 - ...record.presentation ? { presentation: record.presentation } : {},
161 - ...record.category ? { category: record.category } : {},
162 - ...record.description ? { description: record.description } : {},
163 - ...record.help ? { help: record.help } : {},
164 - ...record.keywords ? { keywords: record.keywords } : {},
165 - ...record.actions ? { actions: record.actions } : {}
260 + ...actions ? {
261 + actions: withRenderableIcons(
262 + actions,
263 + actions === record.actions
264 + )
265 + } : {},
266 + ...recordOverlay(record)
166 267 };
167 268 } catch {
168 269 return null;
169 270 }
@@ -175,8 +276,63 @@
175 276 setWidgetTypes(
176 277 results.filter((t) => t !== null)
177 278 );
178 279 setIsResolvingWidgetTypes(false);
280 + for (const record of records) {
281 + if (!record.icon) {
282 + continue;
283 + }
284 + void resolveIcon(record.icon).then((resolved) => {
285 + if (cancelled) {
286 + return;
287 + }
288 + setWidgetTypes(
289 + (prev) => prev.map((widgetType) => {
290 + if (widgetType.name !== record.name) {
291 + return widgetType;
292 + }
293 + if (resolved) {
294 + return { ...widgetType, icon: resolved };
295 + }
296 + return widgetType.icon === pendingIcon ? { ...widgetType, icon: void 0 } : widgetType;
297 + })
298 + );
299 + });
300 + }
301 + for (const record of records) {
302 + for (const action of record.actions ?? []) {
303 + if (typeof action.icon !== "string") {
304 + continue;
305 + }
306 + void resolveIcon(action.icon).then((resolved) => {
307 + if (cancelled) {
308 + return;
309 + }
310 + setWidgetTypes(
311 + (prev) => prev.map((type) => {
312 + if (type.name !== record.name) {
313 + return type;
314 + }
315 + return {
316 + ...type,
317 + actions: type.actions?.map((entry) => {
318 + if (entry.id !== action.id) {
319 + return entry;
320 + }
321 + if (resolved) {
322 + return {
323 + ...entry,
324 + icon: resolved
325 + };
326 + }
327 + return entry.icon === pendingIcon ? { ...entry, icon: void 0 } : entry;
328 + })
329 + };
330 + })
331 + );
332 + });
333 + }
334 + }
179 335 });
180 336 return () => {
181 337 cancelled = true;
182 338 };
@@ -182,10 +338,49 @@
182 338 };
183 339 }, [records]);
184 340 return [widgetTypes, isResolvingWidgetTypes];
185 341 }
342 +
343 +// packages/widget-primitives/build-module/widget-host/widget-host.mjs
344 +var import_element3 = __toESM(require_element(), 1);
345 +var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
346 +var WidgetHostContext = (0, import_element3.createContext)({});
347 +function WidgetHostProvider({
348 + value,
349 + children
350 +}) {
351 + const inherited = (0, import_element3.useContext)(WidgetHostContext);
352 + const merged = (0, import_element3.useMemo)(
353 + () => ({ ...inherited, ...value }),
354 + [inherited, value]
355 + );
356 + return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(WidgetHostContext.Provider, { value: merged, children });
357 +}
358 +function useWidgetHost() {
359 + return (0, import_element3.useContext)(WidgetHostContext);
360 +}
361 +
362 +// packages/widget-primitives/build-module/widget-host/host-link.mjs
363 +var import_element4 = __toESM(require_element(), 1);
364 +var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
365 +var HostLink = (0, import_element4.forwardRef)(
366 + function HostLink2({ href, children, ...props }, ref) {
367 + const { links } = useWidgetHost();
368 + const { download, target } = props;
369 + const opensNewDocument = download !== void 0 && download !== false || /^_blank$/i.test(target ?? "");
370 + const path = links && !opensNewDocument ? links.match(href) : null;
371 + if (links && path !== null) {
372 + return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(links.Link, { ref, path, ...props, children });
373 + }
374 + return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { ref, href, ...props, children });
375 + }
376 +);
186 377 export {
378 + HostLink,
379 + WidgetHostProvider,
187 380 WidgetRender,
188 381 registerFieldType,
382 + registerIconResolver,
383 + useWidgetHost,
189 384 useWidgetTypes
190 385 };
191 386 //# sourceMappingURL=index.js.map