@wordpress/fields 0.30.0 → 0.30.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.
@@ -345,9 +345,21 @@ function MediaEdit({
345
345
  hideLabelFromVision,
346
346
  allowedTypes = ["image"],
347
347
  multiple,
348
- isExpanded
348
+ isExpanded,
349
+ validity
349
350
  }) {
350
351
  const value = field.getValue({ item: data });
352
+ const [isTouched, setIsTouched] = (0, import_element.useState)(false);
353
+ const validityTargetRef = (0, import_element.useRef)(null);
354
+ const [customValidity, setCustomValidity] = (0, import_element.useState)(void 0);
355
+ (0, import_element.useEffect)(() => {
356
+ const validityTarget = validityTargetRef.current;
357
+ const handler = () => {
358
+ setIsTouched(true);
359
+ };
360
+ validityTarget?.addEventListener("invalid", handler);
361
+ return () => validityTarget?.removeEventListener("invalid", handler);
362
+ }, []);
351
363
  const attachments = (0, import_data.useSelect)(
352
364
  (select) => {
353
365
  if (!value) {
@@ -368,11 +380,15 @@ function MediaEdit({
368
380
  (newValue) => onChange(field.setValue({ item: data, value: newValue })),
369
381
  [data, field, onChange]
370
382
  );
371
- const removeItem = (itemId) => {
372
- const currentIds = Array.isArray(value) ? value : [value];
373
- const newIds = currentIds.filter((id) => id !== itemId);
374
- onChangeControl(newIds.length ? newIds : void 0);
375
- };
383
+ const removeItem = (0, import_element.useCallback)(
384
+ (itemId) => {
385
+ const currentIds = Array.isArray(value) ? value : [value];
386
+ const newIds = currentIds.filter((id) => id !== itemId);
387
+ setIsTouched(true);
388
+ onChangeControl(newIds.length ? newIds : void 0);
389
+ },
390
+ [value, onChangeControl]
391
+ );
376
392
  const onFilesDrop = (0, import_element.useCallback)(
377
393
  (files, _replacementId) => {
378
394
  (0, import_media_utils.uploadMedia)({
@@ -454,41 +470,113 @@ function MediaEdit({
454
470
  items.push(...blobItems);
455
471
  return items;
456
472
  }, [attachments, replacementId, blobs]);
457
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("fieldset", { className: "fields__media-edit", "data-field-id": field.id, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
458
- ConditionalMediaUpload,
459
- {
460
- onSelect: (selectedMedia) => {
461
- if (multiple) {
462
- const newIds = Array.isArray(selectedMedia) ? selectedMedia.map((m) => m.id) : [selectedMedia.id];
463
- onChangeControl(newIds);
464
- } else {
465
- onChangeControl(selectedMedia.id);
473
+ (0, import_element.useEffect)(() => {
474
+ if (!isTouched) {
475
+ return;
476
+ }
477
+ const input = validityTargetRef.current;
478
+ if (!input) {
479
+ return;
480
+ }
481
+ if (validity) {
482
+ const customValidityResult = validity?.custom;
483
+ setCustomValidity(customValidityResult);
484
+ if (customValidityResult?.type === "invalid") {
485
+ input.setCustomValidity(
486
+ customValidityResult.message || (0, import_i18n.__)("Invalid")
487
+ );
488
+ } else {
489
+ input.setCustomValidity("");
490
+ }
491
+ } else {
492
+ input.setCustomValidity("");
493
+ setCustomValidity(void 0);
494
+ }
495
+ }, [isTouched, field.isValid, validity]);
496
+ const onBlur = (0, import_element.useCallback)(
497
+ (event) => {
498
+ if (isTouched) {
499
+ return;
500
+ }
501
+ if (!event.relatedTarget || !event.currentTarget.contains(event.relatedTarget)) {
502
+ setIsTouched(true);
503
+ }
504
+ },
505
+ [isTouched]
506
+ );
507
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { onBlur, children: [
508
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("fieldset", { className: "fields__media-edit", "data-field-id": field.id, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
509
+ ConditionalMediaUpload,
510
+ {
511
+ onSelect: (selectedMedia) => {
512
+ if (multiple) {
513
+ const newIds = Array.isArray(selectedMedia) ? selectedMedia.map((m) => m.id) : [selectedMedia.id];
514
+ onChangeControl(newIds);
515
+ } else {
516
+ onChangeControl(selectedMedia.id);
517
+ }
518
+ },
519
+ allowedTypes,
520
+ value,
521
+ multiple,
522
+ title: field.label,
523
+ render: ({ open }) => {
524
+ const AttachmentsComponent = isExpanded ? ExpandedMediaEditAttachments : CompactMediaEditAttachments;
525
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 2, children: [
526
+ field.label && (hideLabelFromVision ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.VisuallyHidden, { as: "legend", children: field.label }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.BaseControl.VisualLabel, { as: "legend", children: field.label })),
527
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
528
+ AttachmentsComponent,
529
+ {
530
+ allItems,
531
+ addButtonLabel,
532
+ multiple,
533
+ removeItem,
534
+ open,
535
+ onFilesDrop,
536
+ isUploading: !!blobs.length
537
+ }
538
+ ),
539
+ field.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalText, { variant: "muted", children: field.description })
540
+ ] });
466
541
  }
467
- },
468
- allowedTypes,
469
- value,
470
- multiple,
471
- title: field.label,
472
- render: ({ open }) => {
473
- const AttachmentsComponent = isExpanded ? ExpandedMediaEditAttachments : CompactMediaEditAttachments;
474
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 2, children: [
475
- field.label && (hideLabelFromVision ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.VisuallyHidden, { as: "legend", children: field.label }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.BaseControl.VisualLabel, { as: "legend", children: field.label })),
542
+ }
543
+ ) }),
544
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.VisuallyHidden, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
545
+ "input",
546
+ {
547
+ type: "text",
548
+ ref: validityTargetRef,
549
+ value: value ?? "",
550
+ tabIndex: -1,
551
+ "aria-hidden": "true",
552
+ onChange: () => {
553
+ }
554
+ }
555
+ ) }),
556
+ customValidity && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-live": "polite", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
557
+ "p",
558
+ {
559
+ className: (0, import_clsx.default)(
560
+ "components-validated-control__indicator",
561
+ {
562
+ "is-invalid": customValidity.type === "invalid",
563
+ "is-valid": customValidity.type === "valid"
564
+ }
565
+ ),
566
+ children: [
476
567
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
477
- AttachmentsComponent,
568
+ import_components.Icon,
478
569
  {
479
- allItems,
480
- addButtonLabel,
481
- multiple,
482
- removeItem,
483
- open,
484
- onFilesDrop,
485
- isUploading: !!blobs.length
570
+ className: "components-validated-control__indicator-icon",
571
+ icon: import_icons.error,
572
+ size: 16,
573
+ fill: "currentColor"
486
574
  }
487
575
  ),
488
- field.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalText, { variant: "muted", children: field.description })
489
- ] });
576
+ customValidity.message
577
+ ]
490
578
  }
491
- }
492
- ) });
579
+ ) })
580
+ ] });
493
581
  }
494
582
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/media-edit/index.tsx"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tDropZone,\n\tIcon,\n\tSpinner,\n\t__experimentalText as Text,\n\t__experimentalTruncate as Truncate,\n\t__experimentalVStack as VStack,\n\tBaseControl,\n\tTooltip,\n\tVisuallyHidden,\n} from '@wordpress/components';\nimport { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';\nimport { store as coreStore, type Attachment } from '@wordpress/core-data';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useCallback, useMemo, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { archive, audio, video, file, closeSmall } from '@wordpress/icons';\nimport {\n\tMediaUpload,\n\tuploadMedia,\n\tprivateApis as mediaUtilsPrivateApis,\n} from '@wordpress/media-utils';\nimport { store as noticesStore } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport type { MediaEditProps } from '../../types';\n\nconst { MediaUploadModal } = unlock( mediaUtilsPrivateApis );\n\ntype BlobItem = {\n\tid: string;\n\tsource_url: string;\n\tmime_type: string | undefined;\n\talt_text?: string;\n};\n\n/**\n * Conditional Media component that uses MediaUploadModal when experiment is enabled,\n * otherwise falls back to media-utils MediaUpload.\n *\n * @param root0 Component props.\n * @param root0.render Render prop function that receives { open } object.\n * @param root0.multiple Whether to allow multiple media selections.\n * @return The component.\n */\nfunction ConditionalMediaUpload( { render, multiple, ...props }: any ) {\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tif ( ( window as any ).__experimentalDataViewsMediaModal ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ render && render( { open: () => setIsModalOpen( true ) } ) }\n\t\t\t\t{ isModalOpen && (\n\t\t\t\t\t<MediaUploadModal\n\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\tisOpen={ isModalOpen }\n\t\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onClose?.();\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tonSelect={ ( media: any ) => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onSelect?.( media );\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n\t// Fallback to media-utils MediaUpload when experiment is disabled.\n\treturn (\n\t\t<MediaUpload\n\t\t\t{ ...props }\n\t\t\trender={ render }\n\t\t\tmultiple={ multiple ? 'add' : undefined }\n\t\t/>\n\t);\n}\n\nfunction MediaPickerButton( {\n\topen,\n\tchildren,\n\tlabel,\n\tshowTooltip = false,\n\tonFilesDrop,\n\tattachment,\n\tisUploading = false,\n}: {\n\topen: () => void;\n\tchildren: React.ReactNode;\n\tlabel: string;\n\tshowTooltip?: boolean;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tattachment?: MediaEditAttachment;\n\tisUploading?: boolean;\n} ) {\n\tconst isBlob = attachment && isBlobURL( attachment.source_url );\n\tconst mediaPickerButton = (\n\t\t<div\n\t\t\tclassName=\"fields__media-edit-picker-button\"\n\t\t\trole=\"button\"\n\t\t\ttabIndex={ 0 }\n\t\t\tonClick={ () => {\n\t\t\t\tif ( ! isUploading ) {\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\tonKeyDown={ ( event ) => {\n\t\t\t\tif ( isUploading ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( event.key === 'Enter' || event.key === ' ' ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\taria-label={ label }\n\t\t\taria-disabled={ isUploading }\n\t\t>\n\t\t\t{ children }\n\t\t\t{ isBlob && (\n\t\t\t\t<span className=\"fields__media-edit-picker-button-spinner\">\n\t\t\t\t\t<Spinner />\n\t\t\t\t</span>\n\t\t\t) }\n\t\t\t{ ! isUploading && (\n\t\t\t\t<DropZone\n\t\t\t\t\tonFilesDrop={ ( files ) =>\n\t\t\t\t\t\tonFilesDrop( files, attachment?.id as number )\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n\tif ( ! showTooltip ) {\n\t\treturn mediaPickerButton;\n\t}\n\treturn <Tooltip text={ label }>{ mediaPickerButton }</Tooltip>;\n}\n\nconst archiveMimeTypes = [\n\t'application/zip',\n\t'application/x-zip-compressed',\n\t'application/x-rar-compressed',\n\t'application/x-7z-compressed',\n\t'application/x-tar',\n\t'application/x-gzip',\n];\n\nfunction MediaTitle( { attachment }: { attachment: Attachment< 'view' > } ) {\n\treturn (\n\t\t<Truncate className=\"fields__media-edit-filename\">\n\t\t\t{ attachment.title.rendered }\n\t\t</Truncate>\n\t);\n}\n\nfunction MediaEditPlaceholder( props: {\n\topen: () => void;\n\tlabel: string;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tisUploading: boolean;\n} ) {\n\treturn (\n\t\t<MediaPickerButton { ...props }>\n\t\t\t<span className=\"fields__media-edit-placeholder\">\n\t\t\t\t{ props.label }\n\t\t\t</span>\n\t\t</MediaPickerButton>\n\t);\n}\n\nfunction MediaPreview( { attachment }: { attachment: MediaEditAttachment } ) {\n\tconst url = attachment.source_url;\n\tconst mimeType = attachment.mime_type || '';\n\tif ( mimeType.startsWith( 'image' ) ) {\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"fields__media-edit-thumbnail\"\n\t\t\t\talt={ attachment.alt_text || '' }\n\t\t\t\tsrc={ url }\n\t\t\t/>\n\t\t);\n\t} else if ( mimeType.startsWith( 'audio' ) ) {\n\t\treturn <Icon icon={ audio } />;\n\t} else if ( mimeType.startsWith( 'video' ) ) {\n\t\treturn <Icon icon={ video } />;\n\t} else if ( archiveMimeTypes.includes( mimeType ) ) {\n\t\treturn <Icon icon={ archive } />;\n\t}\n\treturn <Icon icon={ file } />;\n}\n\ntype MediaEditAttachment = Attachment< 'view' > | BlobItem;\ninterface MediaEditAttachmentsProps {\n\tallItems: Array< MediaEditAttachment > | null;\n\taddButtonLabel: string;\n\tmultiple?: boolean;\n\tremoveItem: ( itemId: number ) => void;\n\topen: () => void;\n\tonFilesDrop: ( files: File[], attachmentId?: number ) => void;\n\tisUploading: boolean;\n}\n\nfunction ExpandedMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<div\n\t\t\tclassName={ clsx( 'fields__media-edit-expanded', {\n\t\t\t\t'is-multiple': multiple,\n\t\t\t\t'is-single': ! multiple,\n\t\t\t\t'is-empty': ! allItems?.length,\n\t\t\t} ) }\n\t\t>\n\t\t\t{ allItems?.map( ( attachment ) => {\n\t\t\t\tconst hasPreviewImage =\n\t\t\t\t\tattachment.mime_type?.startsWith( 'image' );\n\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\tclassName={ clsx( 'fields__media-edit-expanded-item', {\n\t\t\t\t\t\t\t'has-preview-image': hasPreviewImage,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-preview\">\n\t\t\t\t\t\t\t\t<VStack\n\t\t\t\t\t\t\t\t\tspacing={ 0 }\n\t\t\t\t\t\t\t\t\talignment=\"center\"\n\t\t\t\t\t\t\t\t\tjustify=\"center\"\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-preview-stack\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ ( ! isBlob || hasPreviewImage ) && (\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ ! isBlob &&\n\t\t\t\t\t\t\t\t\t\t( ! hasPreviewImage ? (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-remove\"\n\t\t\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id as number );\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</div>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n\nfunction CompactMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<>\n\t\t\t{ !! allItems?.length && (\n\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t{ allItems.map( ( attachment ) => {\n\t\t\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-compact\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-remove\"\n\t\t\t\t\t\t\t\t\ttext={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\ttypeof attachment.id === 'number'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id );\n\t\t\t\t\t\t\t\t\t\t}\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</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</VStack>\n\t\t\t) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\n/**\n * A media edit control component that provides a media picker UI with upload functionality\n * for selecting WordPress media attachments. Supports both the traditional WordPress media\n * library and the experimental DataViews media modal.\n *\n * This component is intended to be used as the `Edit` property of a field definition when\n * registering fields with `registerEntityField` from `@wordpress/editor`.\n *\n * @template Item - The type of the item being edited.\n *\n * @param {MediaEditProps<Item>} props - The component props.\n * @param {Item} props.data - The item being edited.\n * @param {Object} props.field - The field configuration with getValue and setValue methods.\n * @param {Function} props.onChange - Callback function when the media selection changes.\n * @param {string[]} [props.allowedTypes] - Array of allowed media types. Default `['image']`.\n * @param {boolean} [props.multiple] - Whether to allow multiple media selections. Default `false`.\n * @param {boolean} [props.hideLabelFromVision] - Whether the label should be hidden from vision.\n * @param {boolean} [props.isExpanded] - Whether to render in an expanded form. Default `false`.\n *\n * @return {JSX.Element} The media edit control component.\n *\n * @example\n * ```tsx\n * import { MediaEdit } from '@wordpress/fields';\n * import type { DataFormControlProps } from '@wordpress/dataviews';\n *\n * const featuredImageField = {\n * id: 'featured_media',\n * type: 'media',\n * label: 'Featured Image',\n * Edit: (props: DataFormControlProps<MyPostType>) => (\n * <MediaEdit\n * {...props}\n * allowedTypes={['image']}\n * />\n * ),\n * };\n * ```\n */\nexport default function MediaEdit< Item >( {\n\tdata,\n\tfield,\n\tonChange,\n\thideLabelFromVision,\n\tallowedTypes = [ 'image' ],\n\tmultiple,\n\tisExpanded,\n}: MediaEditProps< Item > ) {\n\tconst value = field.getValue( { item: data } );\n\tconst attachments = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! value ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst normalizedValue = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst { getEntityRecords } = select( coreStore );\n\t\t\treturn getEntityRecords( 'postType', 'attachment', {\n\t\t\t\tinclude: normalizedValue,\n\t\t\t} ) as Attachment< 'view' >[] | null;\n\t\t},\n\t\t[ value ]\n\t);\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\t// Support one upload action at a time for now.\n\tconst [ replacementId, setReplacementId ] = useState< number >();\n\tconst [ blobs, setBlobs ] = useState< string[] >( [] );\n\tconst onChangeControl = useCallback(\n\t\t( newValue: number | number[] | undefined ) =>\n\t\t\tonChange( field.setValue( { item: data, value: newValue } ) ),\n\t\t[ data, field, onChange ]\n\t);\n\tconst removeItem = ( itemId: number ) => {\n\t\tconst currentIds = Array.isArray( value ) ? value : [ value ];\n\t\tconst newIds = currentIds.filter( ( id ) => id !== itemId );\n\t\tonChangeControl( newIds.length ? newIds : undefined );\n\t};\n\tconst onFilesDrop = useCallback(\n\t\t( files: File[], _replacementId?: number ) => {\n\t\t\tuploadMedia( {\n\t\t\t\tallowedTypes: allowedTypes?.length ? allowedTypes : undefined,\n\t\t\t\tfilesList: files,\n\t\t\t\tonFileChange( uploadedMedia: any[] ) {\n\t\t\t\t\tsetReplacementId( _replacementId );\n\t\t\t\t\tconst { blobItems, uploadedItems } = uploadedMedia.reduce(\n\t\t\t\t\t\t( accumulator, item ) => {\n\t\t\t\t\t\t\tif ( isBlobURL( item.url ) ) {\n\t\t\t\t\t\t\t\taccumulator.blobItems.push( item.url );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\taccumulator.uploadedItems.push( item.id );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn accumulator;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblobItems: [] as string[],\n\t\t\t\t\t\t\tuploadedItems: [] as number[],\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tsetBlobs( blobItems );\n\t\t\t\t\t// If all uploads are complete reset the replacementId.\n\t\t\t\t\tif ( uploadedItems.length === uploadedMedia.length ) {\n\t\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! uploadedItems.length ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! multiple ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems[ 0 ] );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! value ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst normalizedValue = Array.isArray( value )\n\t\t\t\t\t\t? value\n\t\t\t\t\t\t: [ value ];\n\t\t\t\t\tconst newIds = [\n\t\t\t\t\t\t...( _replacementId\n\t\t\t\t\t\t\t? normalizedValue.filter(\n\t\t\t\t\t\t\t\t\t( id: any ) => id !== _replacementId\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: normalizedValue ),\n\t\t\t\t\t\t...uploadedItems,\n\t\t\t\t\t];\n\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t},\n\t\t\t\tonError( error: Error ) {\n\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\tsetBlobs( [] );\n\t\t\t\t\tcreateErrorNotice( error.message, { type: 'snackbar' } );\n\t\t\t\t},\n\t\t\t\tmultiple: !! multiple,\n\t\t\t} );\n\t\t},\n\t\t[ allowedTypes, value, multiple, createErrorNotice, onChangeControl ]\n\t);\n\tconst addButtonLabel =\n\t\tfield.placeholder ||\n\t\t( multiple ? __( 'Choose files' ) : __( 'Choose file' ) );\n\t// Merge real attachments with any existing blob items that are being uploaded.\n\tconst allItems: Array< MediaEditAttachment > | null = useMemo( () => {\n\t\tif ( ! blobs.length ) {\n\t\t\treturn attachments;\n\t\t}\n\t\tconst items: Array< MediaEditAttachment > = [\n\t\t\t...( attachments || [] ),\n\t\t];\n\t\tconst blobItems = blobs.map( ( url ) => ( {\n\t\t\tid: url,\n\t\t\tsource_url: url,\n\t\t\tmime_type: getBlobTypeByURL( url ),\n\t\t} ) );\n\t\tconst replacementIndex = items.findIndex(\n\t\t\t( a ) => a.id === replacementId\n\t\t);\n\t\t// Place blobs at the replacement index, when files\n\t\t// dropped in existing media item.\n\t\tif ( replacementIndex !== -1 ) {\n\t\t\treturn [\n\t\t\t\t...items.slice( 0, replacementIndex ),\n\t\t\t\t...blobItems,\n\t\t\t\t...items.slice( replacementIndex + 1 ),\n\t\t\t];\n\t\t}\n\t\titems.push( ...blobItems );\n\t\treturn items;\n\t}, [ attachments, replacementId, blobs ] );\n\treturn (\n\t\t<fieldset className=\"fields__media-edit\" data-field-id={ field.id }>\n\t\t\t<ConditionalMediaUpload\n\t\t\t\tonSelect={ ( selectedMedia: any ) => {\n\t\t\t\t\tif ( multiple ) {\n\t\t\t\t\t\tconst newIds = Array.isArray( selectedMedia )\n\t\t\t\t\t\t\t? selectedMedia.map( ( m: any ) => m.id )\n\t\t\t\t\t\t\t: [ selectedMedia.id ];\n\t\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonChangeControl( selectedMedia.id );\n\t\t\t\t\t}\n\t\t\t\t} }\n\t\t\t\tallowedTypes={ allowedTypes }\n\t\t\t\tvalue={ value }\n\t\t\t\tmultiple={ multiple }\n\t\t\t\ttitle={ field.label }\n\t\t\t\trender={ ( { open }: any ) => {\n\t\t\t\t\tconst AttachmentsComponent = isExpanded\n\t\t\t\t\t\t? ExpandedMediaEditAttachments\n\t\t\t\t\t\t: CompactMediaEditAttachments;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t\t\t{ field.label &&\n\t\t\t\t\t\t\t\t( hideLabelFromVision ? (\n\t\t\t\t\t\t\t\t\t<VisuallyHidden as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t</VisuallyHidden>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<BaseControl.VisualLabel as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t</BaseControl.VisualLabel>\n\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t<AttachmentsComponent\n\t\t\t\t\t\t\t\tallItems={ allItems }\n\t\t\t\t\t\t\t\taddButtonLabel={ addButtonLabel }\n\t\t\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\t\t\tremoveItem={ removeItem }\n\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\tisUploading={ !! blobs.length }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{ field.description && (\n\t\t\t\t\t\t\t\t<Text variant=\"muted\">\n\t\t\t\t\t\t\t\t\t{ field.description }\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</VStack>\n\t\t\t\t\t);\n\t\t\t\t} }\n\t\t\t/>\n\t\t</fieldset>\n\t);\n}\n"],
5
- "mappings": "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",
6
- "names": ["mediaUtilsPrivateApis", "Truncate", "clsx", "VStack", "coreStore", "noticesStore", "Text"]
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tDropZone,\n\tIcon,\n\tSpinner,\n\t__experimentalText as Text,\n\t__experimentalTruncate as Truncate,\n\t__experimentalVStack as VStack,\n\tBaseControl,\n\tTooltip,\n\tVisuallyHidden,\n} from '@wordpress/components';\nimport { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';\nimport { store as coreStore, type Attachment } from '@wordpress/core-data';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport {\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tarchive,\n\taudio,\n\tvideo,\n\tfile,\n\tcloseSmall,\n\terror as errorIcon,\n} from '@wordpress/icons';\nimport {\n\tMediaUpload,\n\tuploadMedia,\n\tprivateApis as mediaUtilsPrivateApis,\n} from '@wordpress/media-utils';\nimport { store as noticesStore } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport type { MediaEditProps } from '../../types';\n\nconst { MediaUploadModal } = unlock( mediaUtilsPrivateApis );\n\ntype BlobItem = {\n\tid: string;\n\tsource_url: string;\n\tmime_type: string | undefined;\n\talt_text?: string;\n};\n\n/**\n * Conditional Media component that uses MediaUploadModal when experiment is enabled,\n * otherwise falls back to media-utils MediaUpload.\n *\n * @param root0 Component props.\n * @param root0.render Render prop function that receives { open } object.\n * @param root0.multiple Whether to allow multiple media selections.\n * @return The component.\n */\nfunction ConditionalMediaUpload( { render, multiple, ...props }: any ) {\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tif ( ( window as any ).__experimentalDataViewsMediaModal ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ render && render( { open: () => setIsModalOpen( true ) } ) }\n\t\t\t\t{ isModalOpen && (\n\t\t\t\t\t<MediaUploadModal\n\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\tisOpen={ isModalOpen }\n\t\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onClose?.();\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tonSelect={ ( media: any ) => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onSelect?.( media );\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n\t// Fallback to media-utils MediaUpload when experiment is disabled.\n\treturn (\n\t\t<MediaUpload\n\t\t\t{ ...props }\n\t\t\trender={ render }\n\t\t\tmultiple={ multiple ? 'add' : undefined }\n\t\t/>\n\t);\n}\n\nfunction MediaPickerButton( {\n\topen,\n\tchildren,\n\tlabel,\n\tshowTooltip = false,\n\tonFilesDrop,\n\tattachment,\n\tisUploading = false,\n}: {\n\topen: () => void;\n\tchildren: React.ReactNode;\n\tlabel: string;\n\tshowTooltip?: boolean;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tattachment?: MediaEditAttachment;\n\tisUploading?: boolean;\n} ) {\n\tconst isBlob = attachment && isBlobURL( attachment.source_url );\n\tconst mediaPickerButton = (\n\t\t<div\n\t\t\tclassName=\"fields__media-edit-picker-button\"\n\t\t\trole=\"button\"\n\t\t\ttabIndex={ 0 }\n\t\t\tonClick={ () => {\n\t\t\t\tif ( ! isUploading ) {\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\tonKeyDown={ ( event ) => {\n\t\t\t\tif ( isUploading ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( event.key === 'Enter' || event.key === ' ' ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\taria-label={ label }\n\t\t\taria-disabled={ isUploading }\n\t\t>\n\t\t\t{ children }\n\t\t\t{ isBlob && (\n\t\t\t\t<span className=\"fields__media-edit-picker-button-spinner\">\n\t\t\t\t\t<Spinner />\n\t\t\t\t</span>\n\t\t\t) }\n\t\t\t{ ! isUploading && (\n\t\t\t\t<DropZone\n\t\t\t\t\tonFilesDrop={ ( files ) =>\n\t\t\t\t\t\tonFilesDrop( files, attachment?.id as number )\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n\tif ( ! showTooltip ) {\n\t\treturn mediaPickerButton;\n\t}\n\treturn <Tooltip text={ label }>{ mediaPickerButton }</Tooltip>;\n}\n\nconst archiveMimeTypes = [\n\t'application/zip',\n\t'application/x-zip-compressed',\n\t'application/x-rar-compressed',\n\t'application/x-7z-compressed',\n\t'application/x-tar',\n\t'application/x-gzip',\n];\n\nfunction MediaTitle( { attachment }: { attachment: Attachment< 'view' > } ) {\n\treturn (\n\t\t<Truncate className=\"fields__media-edit-filename\">\n\t\t\t{ attachment.title.rendered }\n\t\t</Truncate>\n\t);\n}\n\nfunction MediaEditPlaceholder( props: {\n\topen: () => void;\n\tlabel: string;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tisUploading: boolean;\n} ) {\n\treturn (\n\t\t<MediaPickerButton { ...props }>\n\t\t\t<span className=\"fields__media-edit-placeholder\">\n\t\t\t\t{ props.label }\n\t\t\t</span>\n\t\t</MediaPickerButton>\n\t);\n}\n\nfunction MediaPreview( { attachment }: { attachment: MediaEditAttachment } ) {\n\tconst url = attachment.source_url;\n\tconst mimeType = attachment.mime_type || '';\n\tif ( mimeType.startsWith( 'image' ) ) {\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"fields__media-edit-thumbnail\"\n\t\t\t\talt={ attachment.alt_text || '' }\n\t\t\t\tsrc={ url }\n\t\t\t/>\n\t\t);\n\t} else if ( mimeType.startsWith( 'audio' ) ) {\n\t\treturn <Icon icon={ audio } />;\n\t} else if ( mimeType.startsWith( 'video' ) ) {\n\t\treturn <Icon icon={ video } />;\n\t} else if ( archiveMimeTypes.includes( mimeType ) ) {\n\t\treturn <Icon icon={ archive } />;\n\t}\n\treturn <Icon icon={ file } />;\n}\n\ntype MediaEditAttachment = Attachment< 'view' > | BlobItem;\ninterface MediaEditAttachmentsProps {\n\tallItems: Array< MediaEditAttachment > | null;\n\taddButtonLabel: string;\n\tmultiple?: boolean;\n\tremoveItem: ( itemId: number ) => void;\n\topen: () => void;\n\tonFilesDrop: ( files: File[], attachmentId?: number ) => void;\n\tisUploading: boolean;\n}\n\nfunction ExpandedMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<div\n\t\t\tclassName={ clsx( 'fields__media-edit-expanded', {\n\t\t\t\t'is-multiple': multiple,\n\t\t\t\t'is-single': ! multiple,\n\t\t\t\t'is-empty': ! allItems?.length,\n\t\t\t} ) }\n\t\t>\n\t\t\t{ allItems?.map( ( attachment ) => {\n\t\t\t\tconst hasPreviewImage =\n\t\t\t\t\tattachment.mime_type?.startsWith( 'image' );\n\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\tclassName={ clsx( 'fields__media-edit-expanded-item', {\n\t\t\t\t\t\t\t'has-preview-image': hasPreviewImage,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-preview\">\n\t\t\t\t\t\t\t\t<VStack\n\t\t\t\t\t\t\t\t\tspacing={ 0 }\n\t\t\t\t\t\t\t\t\talignment=\"center\"\n\t\t\t\t\t\t\t\t\tjustify=\"center\"\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-preview-stack\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ ( ! isBlob || hasPreviewImage ) && (\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ ! isBlob &&\n\t\t\t\t\t\t\t\t\t\t( ! hasPreviewImage ? (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-remove\"\n\t\t\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id as number );\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</div>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n\nfunction CompactMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<>\n\t\t\t{ !! allItems?.length && (\n\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t{ allItems.map( ( attachment ) => {\n\t\t\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-compact\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-remove\"\n\t\t\t\t\t\t\t\t\ttext={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\ttypeof attachment.id === 'number'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id );\n\t\t\t\t\t\t\t\t\t\t}\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</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</VStack>\n\t\t\t) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\n/**\n * A media edit control component that provides a media picker UI with upload functionality\n * for selecting WordPress media attachments. Supports both the traditional WordPress media\n * library and the experimental DataViews media modal.\n *\n * This component is intended to be used as the `Edit` property of a field definition when\n * registering fields with `registerEntityField` from `@wordpress/editor`.\n *\n * @template Item - The type of the item being edited.\n *\n * @param {MediaEditProps<Item>} props - The component props.\n * @param {Item} props.data - The item being edited.\n * @param {Object} props.field - The field configuration with getValue and setValue methods.\n * @param {Function} props.onChange - Callback function when the media selection changes.\n * @param {string[]} [props.allowedTypes] - Array of allowed media types. Default `['image']`.\n * @param {boolean} [props.multiple] - Whether to allow multiple media selections. Default `false`.\n * @param {boolean} [props.hideLabelFromVision] - Whether the label should be hidden from vision.\n * @param {boolean} [props.isExpanded] - Whether to render in an expanded form. Default `false`.\n *\n * @return {JSX.Element} The media edit control component.\n *\n * @example\n * ```tsx\n * import { MediaEdit } from '@wordpress/fields';\n * import type { DataFormControlProps } from '@wordpress/dataviews';\n *\n * const featuredImageField = {\n * id: 'featured_media',\n * type: 'media',\n * label: 'Featured Image',\n * Edit: (props: DataFormControlProps<MyPostType>) => (\n * <MediaEdit\n * {...props}\n * allowedTypes={['image']}\n * />\n * ),\n * };\n * ```\n */\nexport default function MediaEdit< Item >( {\n\tdata,\n\tfield,\n\tonChange,\n\thideLabelFromVision,\n\tallowedTypes = [ 'image' ],\n\tmultiple,\n\tisExpanded,\n\tvalidity,\n}: MediaEditProps< Item > ) {\n\tconst value = field.getValue( { item: data } );\n\tconst [ isTouched, setIsTouched ] = useState( false );\n\tconst validityTargetRef = useRef< HTMLInputElement >( null );\n\tconst [ customValidity, setCustomValidity ] = useState<\n\t\t| { type: 'valid' | 'validating' | 'invalid'; message?: string }\n\t\t| undefined\n\t>( undefined );\n\t// Listen for invalid event (e.g., form submission, reportValidity())\n\t// to show validation messages even before blur.\n\tuseEffect( () => {\n\t\tconst validityTarget = validityTargetRef.current;\n\t\tconst handler = () => {\n\t\t\tsetIsTouched( true );\n\t\t};\n\t\tvalidityTarget?.addEventListener( 'invalid', handler );\n\t\treturn () => validityTarget?.removeEventListener( 'invalid', handler );\n\t}, [] );\n\tconst attachments = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! value ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst normalizedValue = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst { getEntityRecords } = select( coreStore );\n\t\t\treturn getEntityRecords( 'postType', 'attachment', {\n\t\t\t\tinclude: normalizedValue,\n\t\t\t} ) as Attachment< 'view' >[] | null;\n\t\t},\n\t\t[ value ]\n\t);\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\t// Support one upload action at a time for now.\n\tconst [ replacementId, setReplacementId ] = useState< number >();\n\tconst [ blobs, setBlobs ] = useState< string[] >( [] );\n\tconst onChangeControl = useCallback(\n\t\t( newValue: number | number[] | undefined ) =>\n\t\t\tonChange( field.setValue( { item: data, value: newValue } ) ),\n\t\t[ data, field, onChange ]\n\t);\n\tconst removeItem = useCallback(\n\t\t( itemId: number ) => {\n\t\t\tconst currentIds = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst newIds = currentIds.filter( ( id ) => id !== itemId );\n\t\t\t// Mark as touched to immediately show any validation error.\n\t\t\tsetIsTouched( true );\n\t\t\tonChangeControl( newIds.length ? newIds : undefined );\n\t\t},\n\t\t[ value, onChangeControl ]\n\t);\n\tconst onFilesDrop = useCallback(\n\t\t( files: File[], _replacementId?: number ) => {\n\t\t\tuploadMedia( {\n\t\t\t\tallowedTypes: allowedTypes?.length ? allowedTypes : undefined,\n\t\t\t\tfilesList: files,\n\t\t\t\tonFileChange( uploadedMedia: any[] ) {\n\t\t\t\t\tsetReplacementId( _replacementId );\n\t\t\t\t\tconst { blobItems, uploadedItems } = uploadedMedia.reduce(\n\t\t\t\t\t\t( accumulator, item ) => {\n\t\t\t\t\t\t\tif ( isBlobURL( item.url ) ) {\n\t\t\t\t\t\t\t\taccumulator.blobItems.push( item.url );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\taccumulator.uploadedItems.push( item.id );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn accumulator;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblobItems: [] as string[],\n\t\t\t\t\t\t\tuploadedItems: [] as number[],\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tsetBlobs( blobItems );\n\t\t\t\t\t// If all uploads are complete reset the replacementId.\n\t\t\t\t\tif ( uploadedItems.length === uploadedMedia.length ) {\n\t\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! uploadedItems.length ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! multiple ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems[ 0 ] );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! value ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst normalizedValue = Array.isArray( value )\n\t\t\t\t\t\t? value\n\t\t\t\t\t\t: [ value ];\n\t\t\t\t\tconst newIds = [\n\t\t\t\t\t\t...( _replacementId\n\t\t\t\t\t\t\t? normalizedValue.filter(\n\t\t\t\t\t\t\t\t\t( id: any ) => id !== _replacementId\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: normalizedValue ),\n\t\t\t\t\t\t...uploadedItems,\n\t\t\t\t\t];\n\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t},\n\t\t\t\tonError( error: Error ) {\n\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\tsetBlobs( [] );\n\t\t\t\t\tcreateErrorNotice( error.message, { type: 'snackbar' } );\n\t\t\t\t},\n\t\t\t\tmultiple: !! multiple,\n\t\t\t} );\n\t\t},\n\t\t[ allowedTypes, value, multiple, createErrorNotice, onChangeControl ]\n\t);\n\tconst addButtonLabel =\n\t\tfield.placeholder ||\n\t\t( multiple ? __( 'Choose files' ) : __( 'Choose file' ) );\n\t// Merge real attachments with any existing blob items that are being uploaded.\n\tconst allItems: Array< MediaEditAttachment > | null = useMemo( () => {\n\t\tif ( ! blobs.length ) {\n\t\t\treturn attachments;\n\t\t}\n\t\tconst items: Array< MediaEditAttachment > = [\n\t\t\t...( attachments || [] ),\n\t\t];\n\t\tconst blobItems = blobs.map( ( url ) => ( {\n\t\t\tid: url,\n\t\t\tsource_url: url,\n\t\t\tmime_type: getBlobTypeByURL( url ),\n\t\t} ) );\n\t\tconst replacementIndex = items.findIndex(\n\t\t\t( a ) => a.id === replacementId\n\t\t);\n\t\t// Place blobs at the replacement index, when files\n\t\t// dropped in existing media item.\n\t\tif ( replacementIndex !== -1 ) {\n\t\t\treturn [\n\t\t\t\t...items.slice( 0, replacementIndex ),\n\t\t\t\t...blobItems,\n\t\t\t\t...items.slice( replacementIndex + 1 ),\n\t\t\t];\n\t\t}\n\t\titems.push( ...blobItems );\n\t\treturn items;\n\t}, [ attachments, replacementId, blobs ] );\n\tuseEffect( () => {\n\t\tif ( ! isTouched ) {\n\t\t\treturn;\n\t\t}\n\t\tconst input = validityTargetRef.current;\n\t\tif ( ! input ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( validity ) {\n\t\t\tconst customValidityResult = validity?.custom;\n\t\t\tsetCustomValidity( customValidityResult );\n\n\t\t\t// Set custom validity on hidden input for HTML5 form validation.\n\t\t\tif ( customValidityResult?.type === 'invalid' ) {\n\t\t\t\tinput.setCustomValidity(\n\t\t\t\t\tcustomValidityResult.message || __( 'Invalid' )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tinput.setCustomValidity( '' ); // Clear validity\n\t\t\t}\n\t\t} else {\n\t\t\t// Clear any previous validation.\n\t\t\tinput.setCustomValidity( '' );\n\t\t\tsetCustomValidity( undefined );\n\t\t}\n\t}, [ isTouched, field.isValid, validity ] );\n\tconst onBlur = useCallback(\n\t\t( event: React.FocusEvent< HTMLElement > ) => {\n\t\t\tif ( isTouched ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t! event.relatedTarget ||\n\t\t\t\t! event.currentTarget.contains( event.relatedTarget )\n\t\t\t) {\n\t\t\t\tsetIsTouched( true );\n\t\t\t}\n\t\t},\n\t\t[ isTouched ]\n\t);\n\treturn (\n\t\t<div onBlur={ onBlur }>\n\t\t\t<fieldset className=\"fields__media-edit\" data-field-id={ field.id }>\n\t\t\t\t<ConditionalMediaUpload\n\t\t\t\t\tonSelect={ ( selectedMedia: any ) => {\n\t\t\t\t\t\tif ( multiple ) {\n\t\t\t\t\t\t\tconst newIds = Array.isArray( selectedMedia )\n\t\t\t\t\t\t\t\t? selectedMedia.map( ( m: any ) => m.id )\n\t\t\t\t\t\t\t\t: [ selectedMedia.id ];\n\t\t\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tonChangeControl( selectedMedia.id );\n\t\t\t\t\t\t}\n\t\t\t\t\t} }\n\t\t\t\t\tallowedTypes={ allowedTypes }\n\t\t\t\t\tvalue={ value }\n\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\ttitle={ field.label }\n\t\t\t\t\trender={ ( { open }: any ) => {\n\t\t\t\t\t\tconst AttachmentsComponent = isExpanded\n\t\t\t\t\t\t\t? ExpandedMediaEditAttachments\n\t\t\t\t\t\t\t: CompactMediaEditAttachments;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t\t\t\t{ field.label &&\n\t\t\t\t\t\t\t\t\t( hideLabelFromVision ? (\n\t\t\t\t\t\t\t\t\t\t<VisuallyHidden as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t\t</VisuallyHidden>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<BaseControl.VisualLabel as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t\t</BaseControl.VisualLabel>\n\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t<AttachmentsComponent\n\t\t\t\t\t\t\t\t\tallItems={ allItems }\n\t\t\t\t\t\t\t\t\taddButtonLabel={ addButtonLabel }\n\t\t\t\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\t\t\t\tremoveItem={ removeItem }\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tisUploading={ !! blobs.length }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{ field.description && (\n\t\t\t\t\t\t\t\t\t<Text variant=\"muted\">\n\t\t\t\t\t\t\t\t\t\t{ field.description }\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t);\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t</fieldset>\n\t\t\t{ /* Visually hidden text input for validation. */ }\n\t\t\t<VisuallyHidden>\n\t\t\t\t<input\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tref={ validityTargetRef }\n\t\t\t\t\tvalue={ value ?? '' }\n\t\t\t\t\ttabIndex={ -1 }\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tonChange={ () => {} }\n\t\t\t\t/>\n\t\t\t</VisuallyHidden>\n\t\t\t{ customValidity && (\n\t\t\t\t<div aria-live=\"polite\">\n\t\t\t\t\t<p\n\t\t\t\t\t\tclassName={ clsx(\n\t\t\t\t\t\t\t'components-validated-control__indicator',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'is-invalid': customValidity.type === 'invalid',\n\t\t\t\t\t\t\t\t'is-valid': customValidity.type === 'valid',\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\t<Icon\n\t\t\t\t\t\t\tclassName=\"components-validated-control__indicator-icon\"\n\t\t\t\t\t\t\ticon={ errorIcon }\n\t\t\t\t\t\t\tsize={ 16 }\n\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ customValidity.message }\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAiB;AAKjB,wBAWO;AACP,kBAA4C;AAC5C,uBAAoD;AACpD,kBAAuC;AACvC,qBAMO;AACP,kBAAmB;AACnB,mBAOO;AACP,yBAIO;AACP,qBAAsC;AAKtC,yBAAuB;AAyBpB;AAtBH,IAAM,EAAE,iBAAiB,QAAI,2BAAQ,mBAAAA,WAAsB;AAkB3D,SAAS,uBAAwB,EAAE,QAAQ,UAAU,GAAG,MAAM,GAAS;AACtE,QAAM,CAAE,aAAa,cAAe,QAAI,yBAAU,KAAM;AACxD,MAAO,OAAgB,mCAAoC;AAC1D,WACC,4EACG;AAAA,gBAAU,OAAQ,EAAE,MAAM,MAAM,eAAgB,IAAK,EAAE,CAAE;AAAA,MACzD,eACD;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACL;AAAA,UACA,QAAS;AAAA,UACT,SAAU,MAAM;AACf,2BAAgB,KAAM;AACtB,kBAAM,UAAU;AAAA,UACjB;AAAA,UACA,UAAW,CAAE,UAAgB;AAC5B,2BAAgB,KAAM;AACtB,kBAAM,WAAY,KAAM;AAAA,UACzB;AAAA;AAAA,MACD;AAAA,OAEF;AAAA,EAEF;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACL;AAAA,MACA,UAAW,WAAW,QAAQ;AAAA;AAAA,EAC/B;AAEF;AAEA,SAAS,kBAAmB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,cAAc;AACf,GAQI;AACH,QAAM,SAAS,kBAAc,uBAAW,WAAW,UAAW;AAC9D,QAAM,oBACL;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,MAAK;AAAA,MACL,UAAW;AAAA,MACX,SAAU,MAAM;AACf,YAAK,CAAE,aAAc;AACpB,eAAK;AAAA,QACN;AAAA,MACD;AAAA,MACA,WAAY,CAAE,UAAW;AACxB,YAAK,aAAc;AAClB;AAAA,QACD;AACA,YAAK,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAM;AACjD,gBAAM,eAAe;AACrB,eAAK;AAAA,QACN;AAAA,MACD;AAAA,MACA,cAAa;AAAA,MACb,iBAAgB;AAAA,MAEd;AAAA;AAAA,QACA,UACD,4CAAC,UAAK,WAAU,4CACf,sDAAC,6BAAQ,GACV;AAAA,QAEC,CAAE,eACH;AAAA,UAAC;AAAA;AAAA,YACA,aAAc,CAAE,UACf,YAAa,OAAO,YAAY,EAAa;AAAA;AAAA,QAE/C;AAAA;AAAA;AAAA,EAEF;AAED,MAAK,CAAE,aAAc;AACpB,WAAO;AAAA,EACR;AACA,SAAO,4CAAC,6BAAQ,MAAO,OAAU,6BAAmB;AACrD;AAEA,IAAM,mBAAmB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAEA,SAAS,WAAY,EAAE,WAAW,GAA0C;AAC3E,SACC,4CAAC,kBAAAC,wBAAA,EAAS,WAAU,+BACjB,qBAAW,MAAM,UACpB;AAEF;AAEA,SAAS,qBAAsB,OAK3B;AACH,SACC,4CAAC,qBAAoB,GAAG,OACvB,sDAAC,UAAK,WAAU,kCACb,gBAAM,OACT,GACD;AAEF;AAEA,SAAS,aAAc,EAAE,WAAW,GAAyC;AAC5E,QAAM,MAAM,WAAW;AACvB,QAAM,WAAW,WAAW,aAAa;AACzC,MAAK,SAAS,WAAY,OAAQ,GAAI;AACrC,WACC;AAAA,MAAC;AAAA;AAAA,QACA,WAAU;AAAA,QACV,KAAM,WAAW,YAAY;AAAA,QAC7B,KAAM;AAAA;AAAA,IACP;AAAA,EAEF,WAAY,SAAS,WAAY,OAAQ,GAAI;AAC5C,WAAO,4CAAC,0BAAK,MAAO,oBAAQ;AAAA,EAC7B,WAAY,SAAS,WAAY,OAAQ,GAAI;AAC5C,WAAO,4CAAC,0BAAK,MAAO,oBAAQ;AAAA,EAC7B,WAAY,iBAAiB,SAAU,QAAS,GAAI;AACnD,WAAO,4CAAC,0BAAK,MAAO,sBAAU;AAAA,EAC/B;AACA,SAAO,4CAAC,0BAAK,MAAO,mBAAO;AAC5B;AAaA,SAAS,6BAA8B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA+B;AAC9B,SACC;AAAA,IAAC;AAAA;AAAA,MACA,eAAY,YAAAC,SAAM,+BAA+B;AAAA,QAChD,eAAe;AAAA,QACf,aAAa,CAAE;AAAA,QACf,YAAY,CAAE,UAAU;AAAA,MACzB,CAAE;AAAA,MAEA;AAAA,kBAAU,IAAK,CAAE,eAAgB;AAClC,gBAAM,kBACL,WAAW,WAAW,WAAY,OAAQ;AAC3C,gBAAM,aAAS,uBAAW,WAAW,UAAW;AAChD,iBACC;AAAA,YAAC;AAAA;AAAA,cAEA,eAAY,YAAAA,SAAM,oCAAoC;AAAA,gBACrD,qBAAqB;AAAA,cACtB,CAAE;AAAA,cAEF;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACA;AAAA,oBACA,WAAQ,gBAAI,SAAU;AAAA,oBACtB,aAAW;AAAA,oBACX;AAAA,oBACA;AAAA,oBACA;AAAA,oBAEA,sDAAC,SAAI,WAAU,uCACd;AAAA,sBAAC,kBAAAC;AAAA,sBAAA;AAAA,wBACA,SAAU;AAAA,wBACV,WAAU;AAAA,wBACV,SAAQ;AAAA,wBACR,WAAU;AAAA,wBAEN;AAAA,4BAAE,UAAU,oBACf;AAAA,4BAAC;AAAA;AAAA,8BACA;AAAA;AAAA,0BACD;AAAA,0BAEC,CAAE,WACD,CAAE,kBACH;AAAA,4BAAC;AAAA;AAAA,8BACA;AAAA;AAAA,0BAGD,IAEA,4CAAC,SAAI,WAAU,uCACd,sDAAC,SAAI,WAAU,qCACd;AAAA,4BAAC;AAAA;AAAA,8BACA;AAAA;AAAA,0BAGD,GACD,GACD;AAAA;AAAA;AAAA,oBAEH,GACD;AAAA;AAAA,gBACD;AAAA,gBACE,CAAE,UACH,4CAAC,SAAI,WAAU,uCACd;AAAA,kBAAC;AAAA;AAAA,oBACA,uBAAqB;AAAA,oBACrB,WAAU;AAAA,oBACV,MAAO;AAAA,oBACP,WAAQ,gBAAI,QAAS;AAAA,oBACrB,MAAK;AAAA,oBACL,UAAW;AAAA,oBACX,wBAAsB;AAAA,oBACtB,SAAU,CACT,UACI;AACJ,4BAAM,gBAAgB;AACtB,iCAAY,WAAW,EAAa;AAAA,oBACrC;AAAA;AAAA,gBACD,GACD;AAAA;AAAA;AAAA,YA/DK,WAAW;AAAA,UAiElB;AAAA,QAEF,CAAE;AAAA,SACE,YAAY,CAAE,UAAU,WAC3B;AAAA,UAAC;AAAA;AAAA,YACA;AAAA,YACA,OAAQ;AAAA,YACR;AAAA,YACA;AAAA;AAAA,QACD;AAAA;AAAA;AAAA,EAEF;AAEF;AAEA,SAAS,4BAA6B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA+B;AAC9B,SACC,4EACG;AAAA,KAAC,CAAE,UAAU,UACd,4CAAC,kBAAAA,sBAAA,EAAO,SAAU,GACf,mBAAS,IAAK,CAAE,eAAgB;AACjC,YAAM,aAAS,uBAAW,WAAW,UAAW;AAChD,aACC;AAAA,QAAC;AAAA;AAAA,UAEA,WAAU;AAAA,UAEV;AAAA;AAAA,cAAC;AAAA;AAAA,gBACA;AAAA,gBACA,WAAQ,gBAAI,SAAU;AAAA,gBACtB,aAAW;AAAA,gBACX;AAAA,gBACA;AAAA,gBACA;AAAA,gBAEA,sFACC;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACA;AAAA;AAAA,kBACD;AAAA,kBACE,CAAE,UACH;AAAA,oBAAC;AAAA;AAAA,sBACA;AAAA;AAAA,kBAGD;AAAA,mBAEF;AAAA;AAAA,YACD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACA,uBAAqB;AAAA,gBACrB,WAAU;AAAA,gBACV,UAAO,gBAAI,QAAS;AAAA,gBACpB,SAAQ;AAAA,gBACR,UAAW;AAAA,gBACX,wBAAsB;AAAA,gBACtB,SAAU,CACT,UACI;AACJ,wBAAM,gBAAgB;AACtB,sBACC,OAAO,WAAW,OAAO,UACxB;AACD,+BAAY,WAAW,EAAG;AAAA,kBAC3B;AAAA,gBACD;AAAA;AAAA,YACD;AAAA;AAAA;AAAA,QAzCM,WAAW;AAAA,MA0ClB;AAAA,IAEF,CAAE,GACH;AAAA,KAEG,YAAY,CAAE,UAAU,WAC3B;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,OAAQ;AAAA,QACR;AAAA,QACA;AAAA;AAAA,IACD;AAAA,KAEF;AAEF;AAyCe,SAAR,UAAoC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe,CAAE,OAAQ;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACD,GAA4B;AAC3B,QAAM,QAAQ,MAAM,SAAU,EAAE,MAAM,KAAK,CAAE;AAC7C,QAAM,CAAE,WAAW,YAAa,QAAI,yBAAU,KAAM;AACpD,QAAM,wBAAoB,uBAA4B,IAAK;AAC3D,QAAM,CAAE,gBAAgB,iBAAkB,QAAI,yBAG3C,MAAU;AAGb,gCAAW,MAAM;AAChB,UAAM,iBAAiB,kBAAkB;AACzC,UAAM,UAAU,MAAM;AACrB,mBAAc,IAAK;AAAA,IACpB;AACA,oBAAgB,iBAAkB,WAAW,OAAQ;AACrD,WAAO,MAAM,gBAAgB,oBAAqB,WAAW,OAAQ;AAAA,EACtE,GAAG,CAAC,CAAE;AACN,QAAM,kBAAc;AAAA,IACnB,CAAE,WAAY;AACb,UAAK,CAAE,OAAQ;AACd,eAAO;AAAA,MACR;AACA,YAAM,kBAAkB,MAAM,QAAS,KAAM,IAAI,QAAQ,CAAE,KAAM;AACjE,YAAM,EAAE,iBAAiB,IAAI,OAAQ,iBAAAC,KAAU;AAC/C,aAAO,iBAAkB,YAAY,cAAc;AAAA,QAClD,SAAS;AAAA,MACV,CAAE;AAAA,IACH;AAAA,IACA,CAAE,KAAM;AAAA,EACT;AACA,QAAM,EAAE,kBAAkB,QAAI,yBAAa,eAAAC,KAAa;AAExD,QAAM,CAAE,eAAe,gBAAiB,QAAI,yBAAmB;AAC/D,QAAM,CAAE,OAAO,QAAS,QAAI,yBAAsB,CAAC,CAAE;AACrD,QAAM,sBAAkB;AAAA,IACvB,CAAE,aACD,SAAU,MAAM,SAAU,EAAE,MAAM,MAAM,OAAO,SAAS,CAAE,CAAE;AAAA,IAC7D,CAAE,MAAM,OAAO,QAAS;AAAA,EACzB;AACA,QAAM,iBAAa;AAAA,IAClB,CAAE,WAAoB;AACrB,YAAM,aAAa,MAAM,QAAS,KAAM,IAAI,QAAQ,CAAE,KAAM;AAC5D,YAAM,SAAS,WAAW,OAAQ,CAAE,OAAQ,OAAO,MAAO;AAE1D,mBAAc,IAAK;AACnB,sBAAiB,OAAO,SAAS,SAAS,MAAU;AAAA,IACrD;AAAA,IACA,CAAE,OAAO,eAAgB;AAAA,EAC1B;AACA,QAAM,kBAAc;AAAA,IACnB,CAAE,OAAe,mBAA6B;AAC7C,0CAAa;AAAA,QACZ,cAAc,cAAc,SAAS,eAAe;AAAA,QACpD,WAAW;AAAA,QACX,aAAc,eAAuB;AACpC,2BAAkB,cAAe;AACjC,gBAAM,EAAE,WAAW,cAAc,IAAI,cAAc;AAAA,YAClD,CAAE,aAAa,SAAU;AACxB,sBAAK,uBAAW,KAAK,GAAI,GAAI;AAC5B,4BAAY,UAAU,KAAM,KAAK,GAAI;AAAA,cACtC,OAAO;AACN,4BAAY,cAAc,KAAM,KAAK,EAAG;AAAA,cACzC;AACA,qBAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,WAAW,CAAC;AAAA,cACZ,eAAe,CAAC;AAAA,YACjB;AAAA,UACD;AACA,mBAAU,SAAU;AAEpB,cAAK,cAAc,WAAW,cAAc,QAAS;AACpD,6BAAkB,MAAU;AAAA,UAC7B;AACA,cAAK,CAAE,cAAc,QAAS;AAC7B;AAAA,UACD;AACA,cAAK,CAAE,UAAW;AACjB,4BAAiB,cAAe,CAAE,CAAE;AACpC;AAAA,UACD;AACA,cAAK,CAAE,OAAQ;AACd,4BAAiB,aAAc;AAC/B;AAAA,UACD;AACA,gBAAM,kBAAkB,MAAM,QAAS,KAAM,IAC1C,QACA,CAAE,KAAM;AACX,gBAAM,SAAS;AAAA,YACd,GAAK,iBACF,gBAAgB;AAAA,cAChB,CAAE,OAAa,OAAO;AAAA,YACtB,IACA;AAAA,YACH,GAAG;AAAA,UACJ;AACA,0BAAiB,MAAO;AAAA,QACzB;AAAA,QACA,QAAS,OAAe;AACvB,2BAAkB,MAAU;AAC5B,mBAAU,CAAC,CAAE;AACb,4BAAmB,MAAM,SAAS,EAAE,MAAM,WAAW,CAAE;AAAA,QACxD;AAAA,QACA,UAAU,CAAC,CAAE;AAAA,MACd,CAAE;AAAA,IACH;AAAA,IACA,CAAE,cAAc,OAAO,UAAU,mBAAmB,eAAgB;AAAA,EACrE;AACA,QAAM,iBACL,MAAM,gBACJ,eAAW,gBAAI,cAAe,QAAI,gBAAI,aAAc;AAEvD,QAAM,eAAgD,wBAAS,MAAM;AACpE,QAAK,CAAE,MAAM,QAAS;AACrB,aAAO;AAAA,IACR;AACA,UAAM,QAAsC;AAAA,MAC3C,GAAK,eAAe,CAAC;AAAA,IACtB;AACA,UAAM,YAAY,MAAM,IAAK,CAAE,SAAW;AAAA,MACzC,IAAI;AAAA,MACJ,YAAY;AAAA,MACZ,eAAW,8BAAkB,GAAI;AAAA,IAClC,EAAI;AACJ,UAAM,mBAAmB,MAAM;AAAA,MAC9B,CAAE,MAAO,EAAE,OAAO;AAAA,IACnB;AAGA,QAAK,qBAAqB,IAAK;AAC9B,aAAO;AAAA,QACN,GAAG,MAAM,MAAO,GAAG,gBAAiB;AAAA,QACpC,GAAG;AAAA,QACH,GAAG,MAAM,MAAO,mBAAmB,CAAE;AAAA,MACtC;AAAA,IACD;AACA,UAAM,KAAM,GAAG,SAAU;AACzB,WAAO;AAAA,EACR,GAAG,CAAE,aAAa,eAAe,KAAM,CAAE;AACzC,gCAAW,MAAM;AAChB,QAAK,CAAE,WAAY;AAClB;AAAA,IACD;AACA,UAAM,QAAQ,kBAAkB;AAChC,QAAK,CAAE,OAAQ;AACd;AAAA,IACD;AAEA,QAAK,UAAW;AACf,YAAM,uBAAuB,UAAU;AACvC,wBAAmB,oBAAqB;AAGxC,UAAK,sBAAsB,SAAS,WAAY;AAC/C,cAAM;AAAA,UACL,qBAAqB,eAAW,gBAAI,SAAU;AAAA,QAC/C;AAAA,MACD,OAAO;AACN,cAAM,kBAAmB,EAAG;AAAA,MAC7B;AAAA,IACD,OAAO;AAEN,YAAM,kBAAmB,EAAG;AAC5B,wBAAmB,MAAU;AAAA,IAC9B;AAAA,EACD,GAAG,CAAE,WAAW,MAAM,SAAS,QAAS,CAAE;AAC1C,QAAM,aAAS;AAAA,IACd,CAAE,UAA4C;AAC7C,UAAK,WAAY;AAChB;AAAA,MACD;AACA,UACC,CAAE,MAAM,iBACR,CAAE,MAAM,cAAc,SAAU,MAAM,aAAc,GACnD;AACD,qBAAc,IAAK;AAAA,MACpB;AAAA,IACD;AAAA,IACA,CAAE,SAAU;AAAA,EACb;AACA,SACC,6CAAC,SAAI,QACJ;AAAA,gDAAC,cAAS,WAAU,sBAAqB,iBAAgB,MAAM,IAC9D;AAAA,MAAC;AAAA;AAAA,QACA,UAAW,CAAE,kBAAwB;AACpC,cAAK,UAAW;AACf,kBAAM,SAAS,MAAM,QAAS,aAAc,IACzC,cAAc,IAAK,CAAE,MAAY,EAAE,EAAG,IACtC,CAAE,cAAc,EAAG;AACtB,4BAAiB,MAAO;AAAA,UACzB,OAAO;AACN,4BAAiB,cAAc,EAAG;AAAA,UACnC;AAAA,QACD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAQ,MAAM;AAAA,QACd,QAAS,CAAE,EAAE,KAAK,MAAY;AAC7B,gBAAM,uBAAuB,aAC1B,+BACA;AACH,iBACC,6CAAC,kBAAAF,sBAAA,EAAO,SAAU,GACf;AAAA,kBAAM,UACL,sBACD,4CAAC,oCAAe,IAAG,UAChB,gBAAM,OACT,IAEA,4CAAC,8BAAY,aAAZ,EAAwB,IAAG,UACzB,gBAAM,OACT;AAAA,YAEF;AAAA,cAAC;AAAA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,aAAc,CAAC,CAAE,MAAM;AAAA;AAAA,YACxB;AAAA,YACE,MAAM,eACP,4CAAC,kBAAAG,oBAAA,EAAK,SAAQ,SACX,gBAAM,aACT;AAAA,aAEF;AAAA,QAEF;AAAA;AAAA,IACD,GACD;AAAA,IAEA,4CAAC,oCACA;AAAA,MAAC;AAAA;AAAA,QACA,MAAK;AAAA,QACL,KAAM;AAAA,QACN,OAAQ,SAAS;AAAA,QACjB,UAAW;AAAA,QACX,eAAY;AAAA,QACZ,UAAW,MAAM;AAAA,QAAC;AAAA;AAAA,IACnB,GACD;AAAA,IACE,kBACD,4CAAC,SAAI,aAAU,UACd;AAAA,MAAC;AAAA;AAAA,QACA,eAAY,YAAAJ;AAAA,UACX;AAAA,UACA;AAAA,YACC,cAAc,eAAe,SAAS;AAAA,YACtC,YAAY,eAAe,SAAS;AAAA,UACrC;AAAA,QACD;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACA,WAAU;AAAA,cACV,MAAO,aAAAK;AAAA,cACP,MAAO;AAAA,cACP,MAAK;AAAA;AAAA,UACN;AAAA,UACE,eAAe;AAAA;AAAA;AAAA,IAClB,GACD;AAAA,KAEF;AAEF;",
6
+ "names": ["mediaUtilsPrivateApis", "Truncate", "clsx", "VStack", "coreStore", "noticesStore", "Text", "errorIcon"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/types.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { DataFormControlProps } from '@wordpress/dataviews';\n\ntype PostStatus =\n\t| 'publish'\n\t| 'draft'\n\t| 'pending'\n\t| 'private'\n\t| 'future'\n\t| 'auto-draft'\n\t| 'trash';\n\nexport interface CommonPost {\n\tstatus?: PostStatus;\n\ttitle: string | { rendered: string } | { raw: string };\n\tcontent: string | { raw: string; rendered: string };\n\ttype: string;\n\tid: string | number;\n\tblocks?: Object[];\n\t_links?: Links;\n}\n\ninterface Links {\n\t'predecessor-version'?: { href: string; id: number }[];\n\t'version-history'?: { href: string; count: number }[];\n\t[ key: string ]: { href: string }[] | undefined;\n}\n\ninterface Author {\n\tid: number;\n\tname: string;\n\tavatar_urls: Record< string, string >;\n}\n\ninterface EmbeddedAuthor {\n\tauthor: Author[];\n}\n\n/**\n * BasePost interface used for all post types.\n */\nexport interface BasePost extends CommonPost {\n\tcomment_status?: 'open' | 'closed';\n\texcerpt?: string | { raw: string; rendered: string };\n\tmeta?: Record< string, any >;\n\tparent?: number;\n\tpassword?: string;\n\ttemplate?: string;\n\tformat?: string;\n\tfeatured_media?: number;\n\tmenu_order?: number;\n\tping_status?: 'open' | 'closed';\n\tlink?: string;\n\tslug?: string;\n\tpermalink_template?: string;\n\tdate?: string;\n\tmodified?: string;\n\tauthor?: number;\n}\n\nexport interface BasePostWithEmbeddedAuthor extends BasePost {\n\t_embedded: EmbeddedAuthor;\n}\n\ninterface FeaturedMedia {\n\ttitle: {\n\t\trendered: string;\n\t};\n\tsource_url: string;\n\tmedia_details: {\n\t\tsizes: Record< string, { width: number; source_url: string } >;\n\t};\n}\n\ninterface EmbeddedFeaturedMedia {\n\t'wp:featuredmedia': FeaturedMedia[];\n}\n\nexport interface BasePostWithEmbeddedFeaturedMedia extends BasePost {\n\t_embedded: EmbeddedFeaturedMedia;\n}\n\nexport interface Template extends CommonPost {\n\ttype: 'wp_template';\n\tis_custom: boolean;\n\tsource: string;\n\torigin: string;\n\tplugin?: string;\n\thas_theme_file: boolean;\n\tid: string;\n}\n\nexport interface TemplatePart extends CommonPost {\n\ttype: 'wp_template_part';\n\tsource: string;\n\torigin: string;\n\thas_theme_file: boolean;\n\tid: string;\n\tarea: string;\n\tplugin?: string;\n}\n\nexport interface Pattern extends CommonPost {\n\tslug: string;\n\ttitle: { raw: string };\n\twp_pattern_sync_status: string;\n}\n\nexport type Post = Template | TemplatePart | Pattern | BasePost;\n\nexport type PostWithPermissions = Post & {\n\tpermissions: {\n\t\tdelete: boolean;\n\t\tupdate: boolean;\n\t};\n};\n\ninterface EditorSupport {\n\tnotes?: boolean;\n}\n\nexport interface PostType {\n\tslug: string;\n\tviewable: boolean;\n\tsupports?: {\n\t\t'page-attributes'?: boolean;\n\t\ttitle?: boolean;\n\t\trevisions?: boolean;\n\t\tauthor?: string;\n\t\tthumbnail?: string;\n\t\tcomments?: string;\n\t\teditor?: boolean | [ EditorSupport ];\n\t\ttrackbacks?: boolean;\n\t};\n}\n\n// Will be unnecessary after typescript 5.0 upgrade.\nexport type CoreDataError = { message?: string; code?: string };\n\nexport interface MediaEditProps< Item >\n\textends Pick<\n\t\tDataFormControlProps< Item >,\n\t\t'data' | 'field' | 'onChange' | 'hideLabelFromVision'\n\t> {\n\t/**\n\t * Array of allowed media types (e.g., ['image', 'video']).\n\t *\n\t * @default ['image']\n\t */\n\tallowedTypes?: string[];\n\t/**\n\t * Whether to allow multiple media selections.\n\t *\n\t * @default false\n\t */\n\tmultiple?: boolean;\n\t/**\n\t * Whether to render in an expanded form.\n\t *\n\t * @default false\n\t */\n\tisExpanded?: boolean;\n}\n"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { DataFormControlProps } from '@wordpress/dataviews';\n\ntype PostStatus =\n\t| 'publish'\n\t| 'draft'\n\t| 'pending'\n\t| 'private'\n\t| 'future'\n\t| 'auto-draft'\n\t| 'trash';\n\nexport interface CommonPost {\n\tstatus?: PostStatus;\n\ttitle: string | { rendered: string } | { raw: string };\n\tcontent: string | { raw: string; rendered: string };\n\ttype: string;\n\tid: string | number;\n\tblocks?: Object[];\n\t_links?: Links;\n}\n\ninterface Links {\n\t'predecessor-version'?: { href: string; id: number }[];\n\t'version-history'?: { href: string; count: number }[];\n\t[ key: string ]: { href: string }[] | undefined;\n}\n\ninterface Author {\n\tid: number;\n\tname: string;\n\tavatar_urls: Record< string, string >;\n}\n\ninterface EmbeddedAuthor {\n\tauthor: Author[];\n}\n\n/**\n * BasePost interface used for all post types.\n */\nexport interface BasePost extends CommonPost {\n\tcomment_status?: 'open' | 'closed';\n\texcerpt?: string | { raw: string; rendered: string };\n\tmeta?: Record< string, any >;\n\tparent?: number;\n\tpassword?: string;\n\ttemplate?: string;\n\tformat?: string;\n\tfeatured_media?: number;\n\tmenu_order?: number;\n\tping_status?: 'open' | 'closed';\n\tlink?: string;\n\tslug?: string;\n\tpermalink_template?: string;\n\tdate?: string;\n\tmodified?: string;\n\tauthor?: number;\n}\n\nexport interface BasePostWithEmbeddedAuthor extends BasePost {\n\t_embedded: EmbeddedAuthor;\n}\n\ninterface FeaturedMedia {\n\ttitle: {\n\t\trendered: string;\n\t};\n\tsource_url: string;\n\tmedia_details: {\n\t\tsizes: Record< string, { width: number; source_url: string } >;\n\t};\n}\n\ninterface EmbeddedFeaturedMedia {\n\t'wp:featuredmedia': FeaturedMedia[];\n}\n\nexport interface BasePostWithEmbeddedFeaturedMedia extends BasePost {\n\t_embedded: EmbeddedFeaturedMedia;\n}\n\nexport interface Template extends CommonPost {\n\ttype: 'wp_template';\n\tis_custom: boolean;\n\tsource: string;\n\torigin: string;\n\tplugin?: string;\n\thas_theme_file: boolean;\n\tid: string;\n}\n\nexport interface TemplatePart extends CommonPost {\n\ttype: 'wp_template_part';\n\tsource: string;\n\torigin: string;\n\thas_theme_file: boolean;\n\tid: string;\n\tarea: string;\n\tplugin?: string;\n}\n\nexport interface Pattern extends CommonPost {\n\tslug: string;\n\ttitle: { raw: string };\n\twp_pattern_sync_status: string;\n}\n\nexport type Post = Template | TemplatePart | Pattern | BasePost;\n\nexport type PostWithPermissions = Post & {\n\tpermissions: {\n\t\tdelete: boolean;\n\t\tupdate: boolean;\n\t};\n};\n\ninterface EditorSupport {\n\tnotes?: boolean;\n}\n\nexport interface PostType {\n\tslug: string;\n\tviewable: boolean;\n\tsupports?: {\n\t\t'page-attributes'?: boolean;\n\t\ttitle?: boolean;\n\t\trevisions?: boolean;\n\t\tauthor?: string;\n\t\tthumbnail?: string;\n\t\tcomments?: string;\n\t\teditor?: boolean | [ EditorSupport ];\n\t\ttrackbacks?: boolean;\n\t};\n}\n\n// Will be unnecessary after typescript 5.0 upgrade.\nexport type CoreDataError = { message?: string; code?: string };\n\nexport interface MediaEditProps< Item >\n\textends Pick<\n\t\tDataFormControlProps< Item >,\n\t\t'data' | 'field' | 'onChange' | 'hideLabelFromVision' | 'validity'\n\t> {\n\t/**\n\t * Array of allowed media types (e.g., ['image', 'video']).\n\t *\n\t * @default ['image']\n\t */\n\tallowedTypes?: string[];\n\t/**\n\t * Whether to allow multiple media selections.\n\t *\n\t * @default false\n\t */\n\tmultiple?: boolean;\n\t/**\n\t * Whether to render in an expanded form.\n\t *\n\t * @default false\n\t */\n\tisExpanded?: boolean;\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -15,9 +15,22 @@ import {
15
15
  import { isBlobURL, getBlobTypeByURL } from "@wordpress/blob";
16
16
  import { store as coreStore } from "@wordpress/core-data";
17
17
  import { useSelect, useDispatch } from "@wordpress/data";
18
- import { useCallback, useMemo, useState } from "@wordpress/element";
18
+ import {
19
+ useCallback,
20
+ useEffect,
21
+ useMemo,
22
+ useRef,
23
+ useState
24
+ } from "@wordpress/element";
19
25
  import { __ } from "@wordpress/i18n";
20
- import { archive, audio, video, file, closeSmall } from "@wordpress/icons";
26
+ import {
27
+ archive,
28
+ audio,
29
+ video,
30
+ file,
31
+ closeSmall,
32
+ error as errorIcon
33
+ } from "@wordpress/icons";
21
34
  import {
22
35
  MediaUpload,
23
36
  uploadMedia,
@@ -326,9 +339,21 @@ function MediaEdit({
326
339
  hideLabelFromVision,
327
340
  allowedTypes = ["image"],
328
341
  multiple,
329
- isExpanded
342
+ isExpanded,
343
+ validity
330
344
  }) {
331
345
  const value = field.getValue({ item: data });
346
+ const [isTouched, setIsTouched] = useState(false);
347
+ const validityTargetRef = useRef(null);
348
+ const [customValidity, setCustomValidity] = useState(void 0);
349
+ useEffect(() => {
350
+ const validityTarget = validityTargetRef.current;
351
+ const handler = () => {
352
+ setIsTouched(true);
353
+ };
354
+ validityTarget?.addEventListener("invalid", handler);
355
+ return () => validityTarget?.removeEventListener("invalid", handler);
356
+ }, []);
332
357
  const attachments = useSelect(
333
358
  (select) => {
334
359
  if (!value) {
@@ -349,11 +374,15 @@ function MediaEdit({
349
374
  (newValue) => onChange(field.setValue({ item: data, value: newValue })),
350
375
  [data, field, onChange]
351
376
  );
352
- const removeItem = (itemId) => {
353
- const currentIds = Array.isArray(value) ? value : [value];
354
- const newIds = currentIds.filter((id) => id !== itemId);
355
- onChangeControl(newIds.length ? newIds : void 0);
356
- };
377
+ const removeItem = useCallback(
378
+ (itemId) => {
379
+ const currentIds = Array.isArray(value) ? value : [value];
380
+ const newIds = currentIds.filter((id) => id !== itemId);
381
+ setIsTouched(true);
382
+ onChangeControl(newIds.length ? newIds : void 0);
383
+ },
384
+ [value, onChangeControl]
385
+ );
357
386
  const onFilesDrop = useCallback(
358
387
  (files, _replacementId) => {
359
388
  uploadMedia({
@@ -435,42 +464,114 @@ function MediaEdit({
435
464
  items.push(...blobItems);
436
465
  return items;
437
466
  }, [attachments, replacementId, blobs]);
438
- return /* @__PURE__ */ jsx("fieldset", { className: "fields__media-edit", "data-field-id": field.id, children: /* @__PURE__ */ jsx(
439
- ConditionalMediaUpload,
440
- {
441
- onSelect: (selectedMedia) => {
442
- if (multiple) {
443
- const newIds = Array.isArray(selectedMedia) ? selectedMedia.map((m) => m.id) : [selectedMedia.id];
444
- onChangeControl(newIds);
445
- } else {
446
- onChangeControl(selectedMedia.id);
467
+ useEffect(() => {
468
+ if (!isTouched) {
469
+ return;
470
+ }
471
+ const input = validityTargetRef.current;
472
+ if (!input) {
473
+ return;
474
+ }
475
+ if (validity) {
476
+ const customValidityResult = validity?.custom;
477
+ setCustomValidity(customValidityResult);
478
+ if (customValidityResult?.type === "invalid") {
479
+ input.setCustomValidity(
480
+ customValidityResult.message || __("Invalid")
481
+ );
482
+ } else {
483
+ input.setCustomValidity("");
484
+ }
485
+ } else {
486
+ input.setCustomValidity("");
487
+ setCustomValidity(void 0);
488
+ }
489
+ }, [isTouched, field.isValid, validity]);
490
+ const onBlur = useCallback(
491
+ (event) => {
492
+ if (isTouched) {
493
+ return;
494
+ }
495
+ if (!event.relatedTarget || !event.currentTarget.contains(event.relatedTarget)) {
496
+ setIsTouched(true);
497
+ }
498
+ },
499
+ [isTouched]
500
+ );
501
+ return /* @__PURE__ */ jsxs("div", { onBlur, children: [
502
+ /* @__PURE__ */ jsx("fieldset", { className: "fields__media-edit", "data-field-id": field.id, children: /* @__PURE__ */ jsx(
503
+ ConditionalMediaUpload,
504
+ {
505
+ onSelect: (selectedMedia) => {
506
+ if (multiple) {
507
+ const newIds = Array.isArray(selectedMedia) ? selectedMedia.map((m) => m.id) : [selectedMedia.id];
508
+ onChangeControl(newIds);
509
+ } else {
510
+ onChangeControl(selectedMedia.id);
511
+ }
512
+ },
513
+ allowedTypes,
514
+ value,
515
+ multiple,
516
+ title: field.label,
517
+ render: ({ open }) => {
518
+ const AttachmentsComponent = isExpanded ? ExpandedMediaEditAttachments : CompactMediaEditAttachments;
519
+ return /* @__PURE__ */ jsxs(VStack, { spacing: 2, children: [
520
+ field.label && (hideLabelFromVision ? /* @__PURE__ */ jsx(VisuallyHidden, { as: "legend", children: field.label }) : /* @__PURE__ */ jsx(BaseControl.VisualLabel, { as: "legend", children: field.label })),
521
+ /* @__PURE__ */ jsx(
522
+ AttachmentsComponent,
523
+ {
524
+ allItems,
525
+ addButtonLabel,
526
+ multiple,
527
+ removeItem,
528
+ open,
529
+ onFilesDrop,
530
+ isUploading: !!blobs.length
531
+ }
532
+ ),
533
+ field.description && /* @__PURE__ */ jsx(Text, { variant: "muted", children: field.description })
534
+ ] });
447
535
  }
448
- },
449
- allowedTypes,
450
- value,
451
- multiple,
452
- title: field.label,
453
- render: ({ open }) => {
454
- const AttachmentsComponent = isExpanded ? ExpandedMediaEditAttachments : CompactMediaEditAttachments;
455
- return /* @__PURE__ */ jsxs(VStack, { spacing: 2, children: [
456
- field.label && (hideLabelFromVision ? /* @__PURE__ */ jsx(VisuallyHidden, { as: "legend", children: field.label }) : /* @__PURE__ */ jsx(BaseControl.VisualLabel, { as: "legend", children: field.label })),
536
+ }
537
+ ) }),
538
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(
539
+ "input",
540
+ {
541
+ type: "text",
542
+ ref: validityTargetRef,
543
+ value: value ?? "",
544
+ tabIndex: -1,
545
+ "aria-hidden": "true",
546
+ onChange: () => {
547
+ }
548
+ }
549
+ ) }),
550
+ customValidity && /* @__PURE__ */ jsx("div", { "aria-live": "polite", children: /* @__PURE__ */ jsxs(
551
+ "p",
552
+ {
553
+ className: clsx(
554
+ "components-validated-control__indicator",
555
+ {
556
+ "is-invalid": customValidity.type === "invalid",
557
+ "is-valid": customValidity.type === "valid"
558
+ }
559
+ ),
560
+ children: [
457
561
  /* @__PURE__ */ jsx(
458
- AttachmentsComponent,
562
+ Icon,
459
563
  {
460
- allItems,
461
- addButtonLabel,
462
- multiple,
463
- removeItem,
464
- open,
465
- onFilesDrop,
466
- isUploading: !!blobs.length
564
+ className: "components-validated-control__indicator-icon",
565
+ icon: errorIcon,
566
+ size: 16,
567
+ fill: "currentColor"
467
568
  }
468
569
  ),
469
- field.description && /* @__PURE__ */ jsx(Text, { variant: "muted", children: field.description })
470
- ] });
570
+ customValidity.message
571
+ ]
471
572
  }
472
- }
473
- ) });
573
+ ) })
574
+ ] });
474
575
  }
475
576
  export {
476
577
  MediaEdit as default
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/media-edit/index.tsx"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tDropZone,\n\tIcon,\n\tSpinner,\n\t__experimentalText as Text,\n\t__experimentalTruncate as Truncate,\n\t__experimentalVStack as VStack,\n\tBaseControl,\n\tTooltip,\n\tVisuallyHidden,\n} from '@wordpress/components';\nimport { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';\nimport { store as coreStore, type Attachment } from '@wordpress/core-data';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useCallback, useMemo, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { archive, audio, video, file, closeSmall } from '@wordpress/icons';\nimport {\n\tMediaUpload,\n\tuploadMedia,\n\tprivateApis as mediaUtilsPrivateApis,\n} from '@wordpress/media-utils';\nimport { store as noticesStore } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport type { MediaEditProps } from '../../types';\n\nconst { MediaUploadModal } = unlock( mediaUtilsPrivateApis );\n\ntype BlobItem = {\n\tid: string;\n\tsource_url: string;\n\tmime_type: string | undefined;\n\talt_text?: string;\n};\n\n/**\n * Conditional Media component that uses MediaUploadModal when experiment is enabled,\n * otherwise falls back to media-utils MediaUpload.\n *\n * @param root0 Component props.\n * @param root0.render Render prop function that receives { open } object.\n * @param root0.multiple Whether to allow multiple media selections.\n * @return The component.\n */\nfunction ConditionalMediaUpload( { render, multiple, ...props }: any ) {\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tif ( ( window as any ).__experimentalDataViewsMediaModal ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ render && render( { open: () => setIsModalOpen( true ) } ) }\n\t\t\t\t{ isModalOpen && (\n\t\t\t\t\t<MediaUploadModal\n\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\tisOpen={ isModalOpen }\n\t\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onClose?.();\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tonSelect={ ( media: any ) => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onSelect?.( media );\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n\t// Fallback to media-utils MediaUpload when experiment is disabled.\n\treturn (\n\t\t<MediaUpload\n\t\t\t{ ...props }\n\t\t\trender={ render }\n\t\t\tmultiple={ multiple ? 'add' : undefined }\n\t\t/>\n\t);\n}\n\nfunction MediaPickerButton( {\n\topen,\n\tchildren,\n\tlabel,\n\tshowTooltip = false,\n\tonFilesDrop,\n\tattachment,\n\tisUploading = false,\n}: {\n\topen: () => void;\n\tchildren: React.ReactNode;\n\tlabel: string;\n\tshowTooltip?: boolean;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tattachment?: MediaEditAttachment;\n\tisUploading?: boolean;\n} ) {\n\tconst isBlob = attachment && isBlobURL( attachment.source_url );\n\tconst mediaPickerButton = (\n\t\t<div\n\t\t\tclassName=\"fields__media-edit-picker-button\"\n\t\t\trole=\"button\"\n\t\t\ttabIndex={ 0 }\n\t\t\tonClick={ () => {\n\t\t\t\tif ( ! isUploading ) {\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\tonKeyDown={ ( event ) => {\n\t\t\t\tif ( isUploading ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( event.key === 'Enter' || event.key === ' ' ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\taria-label={ label }\n\t\t\taria-disabled={ isUploading }\n\t\t>\n\t\t\t{ children }\n\t\t\t{ isBlob && (\n\t\t\t\t<span className=\"fields__media-edit-picker-button-spinner\">\n\t\t\t\t\t<Spinner />\n\t\t\t\t</span>\n\t\t\t) }\n\t\t\t{ ! isUploading && (\n\t\t\t\t<DropZone\n\t\t\t\t\tonFilesDrop={ ( files ) =>\n\t\t\t\t\t\tonFilesDrop( files, attachment?.id as number )\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n\tif ( ! showTooltip ) {\n\t\treturn mediaPickerButton;\n\t}\n\treturn <Tooltip text={ label }>{ mediaPickerButton }</Tooltip>;\n}\n\nconst archiveMimeTypes = [\n\t'application/zip',\n\t'application/x-zip-compressed',\n\t'application/x-rar-compressed',\n\t'application/x-7z-compressed',\n\t'application/x-tar',\n\t'application/x-gzip',\n];\n\nfunction MediaTitle( { attachment }: { attachment: Attachment< 'view' > } ) {\n\treturn (\n\t\t<Truncate className=\"fields__media-edit-filename\">\n\t\t\t{ attachment.title.rendered }\n\t\t</Truncate>\n\t);\n}\n\nfunction MediaEditPlaceholder( props: {\n\topen: () => void;\n\tlabel: string;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tisUploading: boolean;\n} ) {\n\treturn (\n\t\t<MediaPickerButton { ...props }>\n\t\t\t<span className=\"fields__media-edit-placeholder\">\n\t\t\t\t{ props.label }\n\t\t\t</span>\n\t\t</MediaPickerButton>\n\t);\n}\n\nfunction MediaPreview( { attachment }: { attachment: MediaEditAttachment } ) {\n\tconst url = attachment.source_url;\n\tconst mimeType = attachment.mime_type || '';\n\tif ( mimeType.startsWith( 'image' ) ) {\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"fields__media-edit-thumbnail\"\n\t\t\t\talt={ attachment.alt_text || '' }\n\t\t\t\tsrc={ url }\n\t\t\t/>\n\t\t);\n\t} else if ( mimeType.startsWith( 'audio' ) ) {\n\t\treturn <Icon icon={ audio } />;\n\t} else if ( mimeType.startsWith( 'video' ) ) {\n\t\treturn <Icon icon={ video } />;\n\t} else if ( archiveMimeTypes.includes( mimeType ) ) {\n\t\treturn <Icon icon={ archive } />;\n\t}\n\treturn <Icon icon={ file } />;\n}\n\ntype MediaEditAttachment = Attachment< 'view' > | BlobItem;\ninterface MediaEditAttachmentsProps {\n\tallItems: Array< MediaEditAttachment > | null;\n\taddButtonLabel: string;\n\tmultiple?: boolean;\n\tremoveItem: ( itemId: number ) => void;\n\topen: () => void;\n\tonFilesDrop: ( files: File[], attachmentId?: number ) => void;\n\tisUploading: boolean;\n}\n\nfunction ExpandedMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<div\n\t\t\tclassName={ clsx( 'fields__media-edit-expanded', {\n\t\t\t\t'is-multiple': multiple,\n\t\t\t\t'is-single': ! multiple,\n\t\t\t\t'is-empty': ! allItems?.length,\n\t\t\t} ) }\n\t\t>\n\t\t\t{ allItems?.map( ( attachment ) => {\n\t\t\t\tconst hasPreviewImage =\n\t\t\t\t\tattachment.mime_type?.startsWith( 'image' );\n\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\tclassName={ clsx( 'fields__media-edit-expanded-item', {\n\t\t\t\t\t\t\t'has-preview-image': hasPreviewImage,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-preview\">\n\t\t\t\t\t\t\t\t<VStack\n\t\t\t\t\t\t\t\t\tspacing={ 0 }\n\t\t\t\t\t\t\t\t\talignment=\"center\"\n\t\t\t\t\t\t\t\t\tjustify=\"center\"\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-preview-stack\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ ( ! isBlob || hasPreviewImage ) && (\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ ! isBlob &&\n\t\t\t\t\t\t\t\t\t\t( ! hasPreviewImage ? (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-remove\"\n\t\t\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id as number );\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</div>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n\nfunction CompactMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<>\n\t\t\t{ !! allItems?.length && (\n\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t{ allItems.map( ( attachment ) => {\n\t\t\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-compact\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-remove\"\n\t\t\t\t\t\t\t\t\ttext={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\ttypeof attachment.id === 'number'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id );\n\t\t\t\t\t\t\t\t\t\t}\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</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</VStack>\n\t\t\t) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\n/**\n * A media edit control component that provides a media picker UI with upload functionality\n * for selecting WordPress media attachments. Supports both the traditional WordPress media\n * library and the experimental DataViews media modal.\n *\n * This component is intended to be used as the `Edit` property of a field definition when\n * registering fields with `registerEntityField` from `@wordpress/editor`.\n *\n * @template Item - The type of the item being edited.\n *\n * @param {MediaEditProps<Item>} props - The component props.\n * @param {Item} props.data - The item being edited.\n * @param {Object} props.field - The field configuration with getValue and setValue methods.\n * @param {Function} props.onChange - Callback function when the media selection changes.\n * @param {string[]} [props.allowedTypes] - Array of allowed media types. Default `['image']`.\n * @param {boolean} [props.multiple] - Whether to allow multiple media selections. Default `false`.\n * @param {boolean} [props.hideLabelFromVision] - Whether the label should be hidden from vision.\n * @param {boolean} [props.isExpanded] - Whether to render in an expanded form. Default `false`.\n *\n * @return {JSX.Element} The media edit control component.\n *\n * @example\n * ```tsx\n * import { MediaEdit } from '@wordpress/fields';\n * import type { DataFormControlProps } from '@wordpress/dataviews';\n *\n * const featuredImageField = {\n * id: 'featured_media',\n * type: 'media',\n * label: 'Featured Image',\n * Edit: (props: DataFormControlProps<MyPostType>) => (\n * <MediaEdit\n * {...props}\n * allowedTypes={['image']}\n * />\n * ),\n * };\n * ```\n */\nexport default function MediaEdit< Item >( {\n\tdata,\n\tfield,\n\tonChange,\n\thideLabelFromVision,\n\tallowedTypes = [ 'image' ],\n\tmultiple,\n\tisExpanded,\n}: MediaEditProps< Item > ) {\n\tconst value = field.getValue( { item: data } );\n\tconst attachments = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! value ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst normalizedValue = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst { getEntityRecords } = select( coreStore );\n\t\t\treturn getEntityRecords( 'postType', 'attachment', {\n\t\t\t\tinclude: normalizedValue,\n\t\t\t} ) as Attachment< 'view' >[] | null;\n\t\t},\n\t\t[ value ]\n\t);\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\t// Support one upload action at a time for now.\n\tconst [ replacementId, setReplacementId ] = useState< number >();\n\tconst [ blobs, setBlobs ] = useState< string[] >( [] );\n\tconst onChangeControl = useCallback(\n\t\t( newValue: number | number[] | undefined ) =>\n\t\t\tonChange( field.setValue( { item: data, value: newValue } ) ),\n\t\t[ data, field, onChange ]\n\t);\n\tconst removeItem = ( itemId: number ) => {\n\t\tconst currentIds = Array.isArray( value ) ? value : [ value ];\n\t\tconst newIds = currentIds.filter( ( id ) => id !== itemId );\n\t\tonChangeControl( newIds.length ? newIds : undefined );\n\t};\n\tconst onFilesDrop = useCallback(\n\t\t( files: File[], _replacementId?: number ) => {\n\t\t\tuploadMedia( {\n\t\t\t\tallowedTypes: allowedTypes?.length ? allowedTypes : undefined,\n\t\t\t\tfilesList: files,\n\t\t\t\tonFileChange( uploadedMedia: any[] ) {\n\t\t\t\t\tsetReplacementId( _replacementId );\n\t\t\t\t\tconst { blobItems, uploadedItems } = uploadedMedia.reduce(\n\t\t\t\t\t\t( accumulator, item ) => {\n\t\t\t\t\t\t\tif ( isBlobURL( item.url ) ) {\n\t\t\t\t\t\t\t\taccumulator.blobItems.push( item.url );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\taccumulator.uploadedItems.push( item.id );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn accumulator;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblobItems: [] as string[],\n\t\t\t\t\t\t\tuploadedItems: [] as number[],\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tsetBlobs( blobItems );\n\t\t\t\t\t// If all uploads are complete reset the replacementId.\n\t\t\t\t\tif ( uploadedItems.length === uploadedMedia.length ) {\n\t\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! uploadedItems.length ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! multiple ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems[ 0 ] );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! value ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst normalizedValue = Array.isArray( value )\n\t\t\t\t\t\t? value\n\t\t\t\t\t\t: [ value ];\n\t\t\t\t\tconst newIds = [\n\t\t\t\t\t\t...( _replacementId\n\t\t\t\t\t\t\t? normalizedValue.filter(\n\t\t\t\t\t\t\t\t\t( id: any ) => id !== _replacementId\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: normalizedValue ),\n\t\t\t\t\t\t...uploadedItems,\n\t\t\t\t\t];\n\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t},\n\t\t\t\tonError( error: Error ) {\n\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\tsetBlobs( [] );\n\t\t\t\t\tcreateErrorNotice( error.message, { type: 'snackbar' } );\n\t\t\t\t},\n\t\t\t\tmultiple: !! multiple,\n\t\t\t} );\n\t\t},\n\t\t[ allowedTypes, value, multiple, createErrorNotice, onChangeControl ]\n\t);\n\tconst addButtonLabel =\n\t\tfield.placeholder ||\n\t\t( multiple ? __( 'Choose files' ) : __( 'Choose file' ) );\n\t// Merge real attachments with any existing blob items that are being uploaded.\n\tconst allItems: Array< MediaEditAttachment > | null = useMemo( () => {\n\t\tif ( ! blobs.length ) {\n\t\t\treturn attachments;\n\t\t}\n\t\tconst items: Array< MediaEditAttachment > = [\n\t\t\t...( attachments || [] ),\n\t\t];\n\t\tconst blobItems = blobs.map( ( url ) => ( {\n\t\t\tid: url,\n\t\t\tsource_url: url,\n\t\t\tmime_type: getBlobTypeByURL( url ),\n\t\t} ) );\n\t\tconst replacementIndex = items.findIndex(\n\t\t\t( a ) => a.id === replacementId\n\t\t);\n\t\t// Place blobs at the replacement index, when files\n\t\t// dropped in existing media item.\n\t\tif ( replacementIndex !== -1 ) {\n\t\t\treturn [\n\t\t\t\t...items.slice( 0, replacementIndex ),\n\t\t\t\t...blobItems,\n\t\t\t\t...items.slice( replacementIndex + 1 ),\n\t\t\t];\n\t\t}\n\t\titems.push( ...blobItems );\n\t\treturn items;\n\t}, [ attachments, replacementId, blobs ] );\n\treturn (\n\t\t<fieldset className=\"fields__media-edit\" data-field-id={ field.id }>\n\t\t\t<ConditionalMediaUpload\n\t\t\t\tonSelect={ ( selectedMedia: any ) => {\n\t\t\t\t\tif ( multiple ) {\n\t\t\t\t\t\tconst newIds = Array.isArray( selectedMedia )\n\t\t\t\t\t\t\t? selectedMedia.map( ( m: any ) => m.id )\n\t\t\t\t\t\t\t: [ selectedMedia.id ];\n\t\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonChangeControl( selectedMedia.id );\n\t\t\t\t\t}\n\t\t\t\t} }\n\t\t\t\tallowedTypes={ allowedTypes }\n\t\t\t\tvalue={ value }\n\t\t\t\tmultiple={ multiple }\n\t\t\t\ttitle={ field.label }\n\t\t\t\trender={ ( { open }: any ) => {\n\t\t\t\t\tconst AttachmentsComponent = isExpanded\n\t\t\t\t\t\t? ExpandedMediaEditAttachments\n\t\t\t\t\t\t: CompactMediaEditAttachments;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t\t\t{ field.label &&\n\t\t\t\t\t\t\t\t( hideLabelFromVision ? (\n\t\t\t\t\t\t\t\t\t<VisuallyHidden as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t</VisuallyHidden>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<BaseControl.VisualLabel as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t</BaseControl.VisualLabel>\n\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t<AttachmentsComponent\n\t\t\t\t\t\t\t\tallItems={ allItems }\n\t\t\t\t\t\t\t\taddButtonLabel={ addButtonLabel }\n\t\t\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\t\t\tremoveItem={ removeItem }\n\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\tisUploading={ !! blobs.length }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{ field.description && (\n\t\t\t\t\t\t\t\t<Text variant=\"muted\">\n\t\t\t\t\t\t\t\t\t{ field.description }\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</VStack>\n\t\t\t\t\t);\n\t\t\t\t} }\n\t\t\t/>\n\t\t</fieldset>\n\t);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tDropZone,\n\tIcon,\n\tSpinner,\n\t__experimentalText as Text,\n\t__experimentalTruncate as Truncate,\n\t__experimentalVStack as VStack,\n\tBaseControl,\n\tTooltip,\n\tVisuallyHidden,\n} from '@wordpress/components';\nimport { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';\nimport { store as coreStore, type Attachment } from '@wordpress/core-data';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport {\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tarchive,\n\taudio,\n\tvideo,\n\tfile,\n\tcloseSmall,\n\terror as errorIcon,\n} from '@wordpress/icons';\nimport {\n\tMediaUpload,\n\tuploadMedia,\n\tprivateApis as mediaUtilsPrivateApis,\n} from '@wordpress/media-utils';\nimport { store as noticesStore } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport type { MediaEditProps } from '../../types';\n\nconst { MediaUploadModal } = unlock( mediaUtilsPrivateApis );\n\ntype BlobItem = {\n\tid: string;\n\tsource_url: string;\n\tmime_type: string | undefined;\n\talt_text?: string;\n};\n\n/**\n * Conditional Media component that uses MediaUploadModal when experiment is enabled,\n * otherwise falls back to media-utils MediaUpload.\n *\n * @param root0 Component props.\n * @param root0.render Render prop function that receives { open } object.\n * @param root0.multiple Whether to allow multiple media selections.\n * @return The component.\n */\nfunction ConditionalMediaUpload( { render, multiple, ...props }: any ) {\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tif ( ( window as any ).__experimentalDataViewsMediaModal ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ render && render( { open: () => setIsModalOpen( true ) } ) }\n\t\t\t\t{ isModalOpen && (\n\t\t\t\t\t<MediaUploadModal\n\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\tisOpen={ isModalOpen }\n\t\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onClose?.();\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tonSelect={ ( media: any ) => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onSelect?.( media );\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n\t// Fallback to media-utils MediaUpload when experiment is disabled.\n\treturn (\n\t\t<MediaUpload\n\t\t\t{ ...props }\n\t\t\trender={ render }\n\t\t\tmultiple={ multiple ? 'add' : undefined }\n\t\t/>\n\t);\n}\n\nfunction MediaPickerButton( {\n\topen,\n\tchildren,\n\tlabel,\n\tshowTooltip = false,\n\tonFilesDrop,\n\tattachment,\n\tisUploading = false,\n}: {\n\topen: () => void;\n\tchildren: React.ReactNode;\n\tlabel: string;\n\tshowTooltip?: boolean;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tattachment?: MediaEditAttachment;\n\tisUploading?: boolean;\n} ) {\n\tconst isBlob = attachment && isBlobURL( attachment.source_url );\n\tconst mediaPickerButton = (\n\t\t<div\n\t\t\tclassName=\"fields__media-edit-picker-button\"\n\t\t\trole=\"button\"\n\t\t\ttabIndex={ 0 }\n\t\t\tonClick={ () => {\n\t\t\t\tif ( ! isUploading ) {\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\tonKeyDown={ ( event ) => {\n\t\t\t\tif ( isUploading ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( event.key === 'Enter' || event.key === ' ' ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\taria-label={ label }\n\t\t\taria-disabled={ isUploading }\n\t\t>\n\t\t\t{ children }\n\t\t\t{ isBlob && (\n\t\t\t\t<span className=\"fields__media-edit-picker-button-spinner\">\n\t\t\t\t\t<Spinner />\n\t\t\t\t</span>\n\t\t\t) }\n\t\t\t{ ! isUploading && (\n\t\t\t\t<DropZone\n\t\t\t\t\tonFilesDrop={ ( files ) =>\n\t\t\t\t\t\tonFilesDrop( files, attachment?.id as number )\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n\tif ( ! showTooltip ) {\n\t\treturn mediaPickerButton;\n\t}\n\treturn <Tooltip text={ label }>{ mediaPickerButton }</Tooltip>;\n}\n\nconst archiveMimeTypes = [\n\t'application/zip',\n\t'application/x-zip-compressed',\n\t'application/x-rar-compressed',\n\t'application/x-7z-compressed',\n\t'application/x-tar',\n\t'application/x-gzip',\n];\n\nfunction MediaTitle( { attachment }: { attachment: Attachment< 'view' > } ) {\n\treturn (\n\t\t<Truncate className=\"fields__media-edit-filename\">\n\t\t\t{ attachment.title.rendered }\n\t\t</Truncate>\n\t);\n}\n\nfunction MediaEditPlaceholder( props: {\n\topen: () => void;\n\tlabel: string;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tisUploading: boolean;\n} ) {\n\treturn (\n\t\t<MediaPickerButton { ...props }>\n\t\t\t<span className=\"fields__media-edit-placeholder\">\n\t\t\t\t{ props.label }\n\t\t\t</span>\n\t\t</MediaPickerButton>\n\t);\n}\n\nfunction MediaPreview( { attachment }: { attachment: MediaEditAttachment } ) {\n\tconst url = attachment.source_url;\n\tconst mimeType = attachment.mime_type || '';\n\tif ( mimeType.startsWith( 'image' ) ) {\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"fields__media-edit-thumbnail\"\n\t\t\t\talt={ attachment.alt_text || '' }\n\t\t\t\tsrc={ url }\n\t\t\t/>\n\t\t);\n\t} else if ( mimeType.startsWith( 'audio' ) ) {\n\t\treturn <Icon icon={ audio } />;\n\t} else if ( mimeType.startsWith( 'video' ) ) {\n\t\treturn <Icon icon={ video } />;\n\t} else if ( archiveMimeTypes.includes( mimeType ) ) {\n\t\treturn <Icon icon={ archive } />;\n\t}\n\treturn <Icon icon={ file } />;\n}\n\ntype MediaEditAttachment = Attachment< 'view' > | BlobItem;\ninterface MediaEditAttachmentsProps {\n\tallItems: Array< MediaEditAttachment > | null;\n\taddButtonLabel: string;\n\tmultiple?: boolean;\n\tremoveItem: ( itemId: number ) => void;\n\topen: () => void;\n\tonFilesDrop: ( files: File[], attachmentId?: number ) => void;\n\tisUploading: boolean;\n}\n\nfunction ExpandedMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<div\n\t\t\tclassName={ clsx( 'fields__media-edit-expanded', {\n\t\t\t\t'is-multiple': multiple,\n\t\t\t\t'is-single': ! multiple,\n\t\t\t\t'is-empty': ! allItems?.length,\n\t\t\t} ) }\n\t\t>\n\t\t\t{ allItems?.map( ( attachment ) => {\n\t\t\t\tconst hasPreviewImage =\n\t\t\t\t\tattachment.mime_type?.startsWith( 'image' );\n\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\tclassName={ clsx( 'fields__media-edit-expanded-item', {\n\t\t\t\t\t\t\t'has-preview-image': hasPreviewImage,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-preview\">\n\t\t\t\t\t\t\t\t<VStack\n\t\t\t\t\t\t\t\t\tspacing={ 0 }\n\t\t\t\t\t\t\t\t\talignment=\"center\"\n\t\t\t\t\t\t\t\t\tjustify=\"center\"\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-preview-stack\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ ( ! isBlob || hasPreviewImage ) && (\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ ! isBlob &&\n\t\t\t\t\t\t\t\t\t\t( ! hasPreviewImage ? (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-remove\"\n\t\t\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id as number );\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</div>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n\nfunction CompactMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<>\n\t\t\t{ !! allItems?.length && (\n\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t{ allItems.map( ( attachment ) => {\n\t\t\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-compact\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-remove\"\n\t\t\t\t\t\t\t\t\ttext={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\ttypeof attachment.id === 'number'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id );\n\t\t\t\t\t\t\t\t\t\t}\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</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</VStack>\n\t\t\t) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\n/**\n * A media edit control component that provides a media picker UI with upload functionality\n * for selecting WordPress media attachments. Supports both the traditional WordPress media\n * library and the experimental DataViews media modal.\n *\n * This component is intended to be used as the `Edit` property of a field definition when\n * registering fields with `registerEntityField` from `@wordpress/editor`.\n *\n * @template Item - The type of the item being edited.\n *\n * @param {MediaEditProps<Item>} props - The component props.\n * @param {Item} props.data - The item being edited.\n * @param {Object} props.field - The field configuration with getValue and setValue methods.\n * @param {Function} props.onChange - Callback function when the media selection changes.\n * @param {string[]} [props.allowedTypes] - Array of allowed media types. Default `['image']`.\n * @param {boolean} [props.multiple] - Whether to allow multiple media selections. Default `false`.\n * @param {boolean} [props.hideLabelFromVision] - Whether the label should be hidden from vision.\n * @param {boolean} [props.isExpanded] - Whether to render in an expanded form. Default `false`.\n *\n * @return {JSX.Element} The media edit control component.\n *\n * @example\n * ```tsx\n * import { MediaEdit } from '@wordpress/fields';\n * import type { DataFormControlProps } from '@wordpress/dataviews';\n *\n * const featuredImageField = {\n * id: 'featured_media',\n * type: 'media',\n * label: 'Featured Image',\n * Edit: (props: DataFormControlProps<MyPostType>) => (\n * <MediaEdit\n * {...props}\n * allowedTypes={['image']}\n * />\n * ),\n * };\n * ```\n */\nexport default function MediaEdit< Item >( {\n\tdata,\n\tfield,\n\tonChange,\n\thideLabelFromVision,\n\tallowedTypes = [ 'image' ],\n\tmultiple,\n\tisExpanded,\n\tvalidity,\n}: MediaEditProps< Item > ) {\n\tconst value = field.getValue( { item: data } );\n\tconst [ isTouched, setIsTouched ] = useState( false );\n\tconst validityTargetRef = useRef< HTMLInputElement >( null );\n\tconst [ customValidity, setCustomValidity ] = useState<\n\t\t| { type: 'valid' | 'validating' | 'invalid'; message?: string }\n\t\t| undefined\n\t>( undefined );\n\t// Listen for invalid event (e.g., form submission, reportValidity())\n\t// to show validation messages even before blur.\n\tuseEffect( () => {\n\t\tconst validityTarget = validityTargetRef.current;\n\t\tconst handler = () => {\n\t\t\tsetIsTouched( true );\n\t\t};\n\t\tvalidityTarget?.addEventListener( 'invalid', handler );\n\t\treturn () => validityTarget?.removeEventListener( 'invalid', handler );\n\t}, [] );\n\tconst attachments = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! value ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst normalizedValue = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst { getEntityRecords } = select( coreStore );\n\t\t\treturn getEntityRecords( 'postType', 'attachment', {\n\t\t\t\tinclude: normalizedValue,\n\t\t\t} ) as Attachment< 'view' >[] | null;\n\t\t},\n\t\t[ value ]\n\t);\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\t// Support one upload action at a time for now.\n\tconst [ replacementId, setReplacementId ] = useState< number >();\n\tconst [ blobs, setBlobs ] = useState< string[] >( [] );\n\tconst onChangeControl = useCallback(\n\t\t( newValue: number | number[] | undefined ) =>\n\t\t\tonChange( field.setValue( { item: data, value: newValue } ) ),\n\t\t[ data, field, onChange ]\n\t);\n\tconst removeItem = useCallback(\n\t\t( itemId: number ) => {\n\t\t\tconst currentIds = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst newIds = currentIds.filter( ( id ) => id !== itemId );\n\t\t\t// Mark as touched to immediately show any validation error.\n\t\t\tsetIsTouched( true );\n\t\t\tonChangeControl( newIds.length ? newIds : undefined );\n\t\t},\n\t\t[ value, onChangeControl ]\n\t);\n\tconst onFilesDrop = useCallback(\n\t\t( files: File[], _replacementId?: number ) => {\n\t\t\tuploadMedia( {\n\t\t\t\tallowedTypes: allowedTypes?.length ? allowedTypes : undefined,\n\t\t\t\tfilesList: files,\n\t\t\t\tonFileChange( uploadedMedia: any[] ) {\n\t\t\t\t\tsetReplacementId( _replacementId );\n\t\t\t\t\tconst { blobItems, uploadedItems } = uploadedMedia.reduce(\n\t\t\t\t\t\t( accumulator, item ) => {\n\t\t\t\t\t\t\tif ( isBlobURL( item.url ) ) {\n\t\t\t\t\t\t\t\taccumulator.blobItems.push( item.url );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\taccumulator.uploadedItems.push( item.id );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn accumulator;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblobItems: [] as string[],\n\t\t\t\t\t\t\tuploadedItems: [] as number[],\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tsetBlobs( blobItems );\n\t\t\t\t\t// If all uploads are complete reset the replacementId.\n\t\t\t\t\tif ( uploadedItems.length === uploadedMedia.length ) {\n\t\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! uploadedItems.length ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! multiple ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems[ 0 ] );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! value ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst normalizedValue = Array.isArray( value )\n\t\t\t\t\t\t? value\n\t\t\t\t\t\t: [ value ];\n\t\t\t\t\tconst newIds = [\n\t\t\t\t\t\t...( _replacementId\n\t\t\t\t\t\t\t? normalizedValue.filter(\n\t\t\t\t\t\t\t\t\t( id: any ) => id !== _replacementId\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: normalizedValue ),\n\t\t\t\t\t\t...uploadedItems,\n\t\t\t\t\t];\n\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t},\n\t\t\t\tonError( error: Error ) {\n\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\tsetBlobs( [] );\n\t\t\t\t\tcreateErrorNotice( error.message, { type: 'snackbar' } );\n\t\t\t\t},\n\t\t\t\tmultiple: !! multiple,\n\t\t\t} );\n\t\t},\n\t\t[ allowedTypes, value, multiple, createErrorNotice, onChangeControl ]\n\t);\n\tconst addButtonLabel =\n\t\tfield.placeholder ||\n\t\t( multiple ? __( 'Choose files' ) : __( 'Choose file' ) );\n\t// Merge real attachments with any existing blob items that are being uploaded.\n\tconst allItems: Array< MediaEditAttachment > | null = useMemo( () => {\n\t\tif ( ! blobs.length ) {\n\t\t\treturn attachments;\n\t\t}\n\t\tconst items: Array< MediaEditAttachment > = [\n\t\t\t...( attachments || [] ),\n\t\t];\n\t\tconst blobItems = blobs.map( ( url ) => ( {\n\t\t\tid: url,\n\t\t\tsource_url: url,\n\t\t\tmime_type: getBlobTypeByURL( url ),\n\t\t} ) );\n\t\tconst replacementIndex = items.findIndex(\n\t\t\t( a ) => a.id === replacementId\n\t\t);\n\t\t// Place blobs at the replacement index, when files\n\t\t// dropped in existing media item.\n\t\tif ( replacementIndex !== -1 ) {\n\t\t\treturn [\n\t\t\t\t...items.slice( 0, replacementIndex ),\n\t\t\t\t...blobItems,\n\t\t\t\t...items.slice( replacementIndex + 1 ),\n\t\t\t];\n\t\t}\n\t\titems.push( ...blobItems );\n\t\treturn items;\n\t}, [ attachments, replacementId, blobs ] );\n\tuseEffect( () => {\n\t\tif ( ! isTouched ) {\n\t\t\treturn;\n\t\t}\n\t\tconst input = validityTargetRef.current;\n\t\tif ( ! input ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( validity ) {\n\t\t\tconst customValidityResult = validity?.custom;\n\t\t\tsetCustomValidity( customValidityResult );\n\n\t\t\t// Set custom validity on hidden input for HTML5 form validation.\n\t\t\tif ( customValidityResult?.type === 'invalid' ) {\n\t\t\t\tinput.setCustomValidity(\n\t\t\t\t\tcustomValidityResult.message || __( 'Invalid' )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tinput.setCustomValidity( '' ); // Clear validity\n\t\t\t}\n\t\t} else {\n\t\t\t// Clear any previous validation.\n\t\t\tinput.setCustomValidity( '' );\n\t\t\tsetCustomValidity( undefined );\n\t\t}\n\t}, [ isTouched, field.isValid, validity ] );\n\tconst onBlur = useCallback(\n\t\t( event: React.FocusEvent< HTMLElement > ) => {\n\t\t\tif ( isTouched ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t! event.relatedTarget ||\n\t\t\t\t! event.currentTarget.contains( event.relatedTarget )\n\t\t\t) {\n\t\t\t\tsetIsTouched( true );\n\t\t\t}\n\t\t},\n\t\t[ isTouched ]\n\t);\n\treturn (\n\t\t<div onBlur={ onBlur }>\n\t\t\t<fieldset className=\"fields__media-edit\" data-field-id={ field.id }>\n\t\t\t\t<ConditionalMediaUpload\n\t\t\t\t\tonSelect={ ( selectedMedia: any ) => {\n\t\t\t\t\t\tif ( multiple ) {\n\t\t\t\t\t\t\tconst newIds = Array.isArray( selectedMedia )\n\t\t\t\t\t\t\t\t? selectedMedia.map( ( m: any ) => m.id )\n\t\t\t\t\t\t\t\t: [ selectedMedia.id ];\n\t\t\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tonChangeControl( selectedMedia.id );\n\t\t\t\t\t\t}\n\t\t\t\t\t} }\n\t\t\t\t\tallowedTypes={ allowedTypes }\n\t\t\t\t\tvalue={ value }\n\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\ttitle={ field.label }\n\t\t\t\t\trender={ ( { open }: any ) => {\n\t\t\t\t\t\tconst AttachmentsComponent = isExpanded\n\t\t\t\t\t\t\t? ExpandedMediaEditAttachments\n\t\t\t\t\t\t\t: CompactMediaEditAttachments;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t\t\t\t{ field.label &&\n\t\t\t\t\t\t\t\t\t( hideLabelFromVision ? (\n\t\t\t\t\t\t\t\t\t\t<VisuallyHidden as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t\t</VisuallyHidden>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<BaseControl.VisualLabel as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t\t</BaseControl.VisualLabel>\n\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t<AttachmentsComponent\n\t\t\t\t\t\t\t\t\tallItems={ allItems }\n\t\t\t\t\t\t\t\t\taddButtonLabel={ addButtonLabel }\n\t\t\t\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\t\t\t\tremoveItem={ removeItem }\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tisUploading={ !! blobs.length }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{ field.description && (\n\t\t\t\t\t\t\t\t\t<Text variant=\"muted\">\n\t\t\t\t\t\t\t\t\t\t{ field.description }\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t);\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t</fieldset>\n\t\t\t{ /* Visually hidden text input for validation. */ }\n\t\t\t<VisuallyHidden>\n\t\t\t\t<input\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tref={ validityTargetRef }\n\t\t\t\t\tvalue={ value ?? '' }\n\t\t\t\t\ttabIndex={ -1 }\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tonChange={ () => {} }\n\t\t\t\t/>\n\t\t\t</VisuallyHidden>\n\t\t\t{ customValidity && (\n\t\t\t\t<div aria-live=\"polite\">\n\t\t\t\t\t<p\n\t\t\t\t\t\tclassName={ clsx(\n\t\t\t\t\t\t\t'components-validated-control__indicator',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'is-invalid': customValidity.type === 'invalid',\n\t\t\t\t\t\t\t\t'is-valid': customValidity.type === 'valid',\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\t<Icon\n\t\t\t\t\t\t\tclassName=\"components-validated-control__indicator-icon\"\n\t\t\t\t\t\t\ticon={ errorIcon }\n\t\t\t\t\t\t\tsize={ 16 }\n\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ customValidity.message }\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -397,35 +397,19 @@ fieldset.fields__media-edit .fields__media-edit-expanded:not(.is-empty) .fields_
397
397
  font-weight: 600;
398
398
  }
399
399
 
400
- .dataviews-view-grid__media .fields-controls__featured-image-image,
401
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
402
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
403
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
404
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-image,
405
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
400
+ .fields-controls__featured-image-image,
401
+ .fields-controls__featured-image-placeholder {
406
402
  width: 100%;
407
403
  height: 100%;
408
404
  display: block;
409
405
  border-radius: 4px;
410
406
  }
411
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
412
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
413
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
407
+
408
+ .fields-controls__featured-image-placeholder {
414
409
  box-shadow: none;
415
410
  background: #f0f0f0;
416
411
  }
417
412
 
418
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
419
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder {
420
- width: 32px;
421
- height: 32px;
422
- }
423
-
424
- .dataforms-layouts-panel__field-control .fields-controls__featured-image-image {
425
- width: 16px;
426
- height: 16px;
427
- }
428
-
429
413
  .fields-controls__parent {
430
414
  border: 0;
431
415
  padding: 0;
@@ -397,35 +397,19 @@ fieldset.fields__media-edit .fields__media-edit-expanded:not(.is-empty) .fields_
397
397
  font-weight: 600;
398
398
  }
399
399
 
400
- .dataviews-view-grid__media .fields-controls__featured-image-image,
401
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
402
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
403
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
404
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-image,
405
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
400
+ .fields-controls__featured-image-image,
401
+ .fields-controls__featured-image-placeholder {
406
402
  width: 100%;
407
403
  height: 100%;
408
404
  display: block;
409
405
  border-radius: 4px;
410
406
  }
411
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
412
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
413
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
407
+
408
+ .fields-controls__featured-image-placeholder {
414
409
  box-shadow: none;
415
410
  background: #f0f0f0;
416
411
  }
417
412
 
418
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
419
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder {
420
- width: 32px;
421
- height: 32px;
422
- }
423
-
424
- .dataforms-layouts-panel__field-control .fields-controls__featured-image-image {
425
- width: 16px;
426
- height: 16px;
427
- }
428
-
429
413
  .fields-controls__parent {
430
414
  border: 0;
431
415
  padding: 0;
@@ -38,5 +38,5 @@ import type { MediaEditProps } from '../../types';
38
38
  * };
39
39
  * ```
40
40
  */
41
- export default function MediaEdit<Item>({ data, field, onChange, hideLabelFromVision, allowedTypes, multiple, isExpanded, }: MediaEditProps<Item>): import("react").JSX.Element;
41
+ export default function MediaEdit<Item>({ data, field, onChange, hideLabelFromVision, allowedTypes, multiple, isExpanded, validity, }: MediaEditProps<Item>): import("react").JSX.Element;
42
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-edit/index.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsWlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAE,IAAI,EAAI,EAC1C,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,mBAAmB,EACnB,YAA0B,EAC1B,QAAQ,EACR,UAAU,GACV,EAAE,cAAc,CAAE,IAAI,CAAE,+BA6KxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-edit/index.tsx"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsWlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAE,IAAI,EAAI,EAC1C,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,mBAAmB,EACnB,YAA0B,EAC1B,QAAQ,EACR,UAAU,EACV,QAAQ,GACR,EAAE,cAAc,CAAE,IAAI,CAAE,+BA6QxB"}
@@ -138,7 +138,7 @@ export type CoreDataError = {
138
138
  message?: string;
139
139
  code?: string;
140
140
  };
141
- export interface MediaEditProps<Item> extends Pick<DataFormControlProps<Item>, 'data' | 'field' | 'onChange' | 'hideLabelFromVision'> {
141
+ export interface MediaEditProps<Item> extends Pick<DataFormControlProps<Item>, 'data' | 'field' | 'onChange' | 'hideLabelFromVision' | 'validity'> {
142
142
  /**
143
143
  * Array of allowed media types (e.g., ['image', 'video']).
144
144
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,KAAK,UAAU,GACZ,SAAS,GACT,OAAO,GACP,SAAS,GACT,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,OAAO,CAAC;AAEX,MAAM,WAAW,UAAU;IAC1B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,OAAO,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC;CACf;AAED,UAAU,KAAK;IACd,qBAAqB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,iBAAiB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,CAAE,GAAG,EAAE,MAAM,GAAI;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,SAAS,CAAC;CAChD;AAED,UAAU,MAAM;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,CAAC;CACtC;AAED,UAAU,cAAc;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC3C,cAAc,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,IAAI,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,GAAG,CAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,0BAA2B,SAAQ,QAAQ;IAC3D,SAAS,EAAE,cAAc,CAAC;CAC1B;AAED,UAAU,aAAa;IACtB,KAAK,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE;QACd,KAAK,EAAE,MAAM,CAAE,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAE,CAAC;KAC/D,CAAC;CACF;AAED,UAAU,qBAAqB;IAC9B,kBAAkB,EAAE,aAAa,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,iCAAkC,SAAQ,QAAQ;IAClE,SAAS,EAAE,qBAAqB,CAAC;CACjC;AAED,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC3C,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC/C,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAQ,SAAQ,UAAU;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhE,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG;IACxC,WAAW,EAAE;QACZ,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;KAChB,CAAC;CACF,CAAC;AAEF,UAAU,aAAa;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE;QACV,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,OAAO,GAAG,CAAE,aAAa,CAAE,CAAC;QACrC,UAAU,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACF;AAGD,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,cAAc,CAAE,IAAI,CACpC,SAAQ,IAAI,CACX,oBAAoB,CAAE,IAAI,CAAE,EAC5B,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,qBAAqB,CACrD;IACD;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/fields",
3
- "version": "0.30.0",
3
+ "version": "0.30.1-next.v.0+b8934fcf9",
4
4
  "description": "DataViews is a component that provides an API to render datasets using different types of layouts (table, grid, list, etc.).",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -47,30 +47,30 @@
47
47
  "src/**/*.scss"
48
48
  ],
49
49
  "dependencies": {
50
- "@wordpress/api-fetch": "^7.38.0",
51
- "@wordpress/base-styles": "^6.14.0",
52
- "@wordpress/blob": "^4.38.0",
53
- "@wordpress/block-editor": "^15.11.0",
54
- "@wordpress/blocks": "^15.11.0",
55
- "@wordpress/components": "^32.0.0",
56
- "@wordpress/compose": "^7.38.0",
57
- "@wordpress/core-data": "^7.38.0",
58
- "@wordpress/data": "^10.38.0",
59
- "@wordpress/dataviews": "^11.2.0",
60
- "@wordpress/date": "^5.38.0",
61
- "@wordpress/element": "^6.38.0",
62
- "@wordpress/hooks": "^4.38.0",
63
- "@wordpress/html-entities": "^4.38.0",
64
- "@wordpress/i18n": "^6.11.0",
65
- "@wordpress/icons": "^11.5.0",
66
- "@wordpress/media-utils": "^5.38.0",
67
- "@wordpress/notices": "^5.38.0",
68
- "@wordpress/patterns": "^2.38.0",
69
- "@wordpress/primitives": "^4.38.0",
70
- "@wordpress/private-apis": "^1.38.0",
71
- "@wordpress/router": "^1.38.0",
72
- "@wordpress/url": "^4.38.0",
73
- "@wordpress/warning": "^3.38.0",
50
+ "@wordpress/api-fetch": "^7.38.1-next.v.0+b8934fcf9",
51
+ "@wordpress/base-styles": "^6.14.1-next.v.0+b8934fcf9",
52
+ "@wordpress/blob": "^4.38.1-next.v.0+b8934fcf9",
53
+ "@wordpress/block-editor": "^15.11.1-next.v.0+b8934fcf9",
54
+ "@wordpress/blocks": "^15.11.1-next.v.0+b8934fcf9",
55
+ "@wordpress/components": "^32.0.2-next.v.0+b8934fcf9",
56
+ "@wordpress/compose": "^7.38.1-next.v.0+b8934fcf9",
57
+ "@wordpress/core-data": "^7.38.1-next.v.0+b8934fcf9",
58
+ "@wordpress/data": "^10.38.1-next.v.0+b8934fcf9",
59
+ "@wordpress/dataviews": "^11.3.1-next.v.0+b8934fcf9",
60
+ "@wordpress/date": "^5.38.1-next.v.0+b8934fcf9",
61
+ "@wordpress/element": "^6.38.1-next.v.0+b8934fcf9",
62
+ "@wordpress/hooks": "^4.38.1-next.v.0+b8934fcf9",
63
+ "@wordpress/html-entities": "^4.38.1-next.v.0+b8934fcf9",
64
+ "@wordpress/i18n": "^6.11.1-next.v.0+b8934fcf9",
65
+ "@wordpress/icons": "^11.5.1-next.v.0+b8934fcf9",
66
+ "@wordpress/media-utils": "^5.38.1-next.v.0+b8934fcf9",
67
+ "@wordpress/notices": "^5.38.1-next.v.0+b8934fcf9",
68
+ "@wordpress/patterns": "^2.38.1-next.v.0+b8934fcf9",
69
+ "@wordpress/primitives": "^4.38.1-next.v.0+b8934fcf9",
70
+ "@wordpress/private-apis": "^1.38.1-next.v.0+b8934fcf9",
71
+ "@wordpress/router": "^1.38.1-next.v.0+b8934fcf9",
72
+ "@wordpress/url": "^4.38.1-next.v.0+b8934fcf9",
73
+ "@wordpress/warning": "^3.38.1-next.v.0+b8934fcf9",
74
74
  "change-case": "4.1.2",
75
75
  "client-zip": "^2.4.5",
76
76
  "clsx": "2.1.1",
@@ -82,5 +82,5 @@
82
82
  "publishConfig": {
83
83
  "access": "public"
84
84
  },
85
- "gitHead": "50c4c0f51e4797c217946ce42adfaa5eb026f33f"
85
+ "gitHead": "17529010285784fd2e735348a28391c79de87c88"
86
86
  }
@@ -21,9 +21,22 @@ import {
21
21
  import { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';
22
22
  import { store as coreStore, type Attachment } from '@wordpress/core-data';
23
23
  import { useSelect, useDispatch } from '@wordpress/data';
24
- import { useCallback, useMemo, useState } from '@wordpress/element';
24
+ import {
25
+ useCallback,
26
+ useEffect,
27
+ useMemo,
28
+ useRef,
29
+ useState,
30
+ } from '@wordpress/element';
25
31
  import { __ } from '@wordpress/i18n';
26
- import { archive, audio, video, file, closeSmall } from '@wordpress/icons';
32
+ import {
33
+ archive,
34
+ audio,
35
+ video,
36
+ file,
37
+ closeSmall,
38
+ error as errorIcon,
39
+ } from '@wordpress/icons';
27
40
  import {
28
41
  MediaUpload,
29
42
  uploadMedia,
@@ -440,8 +453,25 @@ export default function MediaEdit< Item >( {
440
453
  allowedTypes = [ 'image' ],
441
454
  multiple,
442
455
  isExpanded,
456
+ validity,
443
457
  }: MediaEditProps< Item > ) {
444
458
  const value = field.getValue( { item: data } );
459
+ const [ isTouched, setIsTouched ] = useState( false );
460
+ const validityTargetRef = useRef< HTMLInputElement >( null );
461
+ const [ customValidity, setCustomValidity ] = useState<
462
+ | { type: 'valid' | 'validating' | 'invalid'; message?: string }
463
+ | undefined
464
+ >( undefined );
465
+ // Listen for invalid event (e.g., form submission, reportValidity())
466
+ // to show validation messages even before blur.
467
+ useEffect( () => {
468
+ const validityTarget = validityTargetRef.current;
469
+ const handler = () => {
470
+ setIsTouched( true );
471
+ };
472
+ validityTarget?.addEventListener( 'invalid', handler );
473
+ return () => validityTarget?.removeEventListener( 'invalid', handler );
474
+ }, [] );
445
475
  const attachments = useSelect(
446
476
  ( select ) => {
447
477
  if ( ! value ) {
@@ -464,11 +494,16 @@ export default function MediaEdit< Item >( {
464
494
  onChange( field.setValue( { item: data, value: newValue } ) ),
465
495
  [ data, field, onChange ]
466
496
  );
467
- const removeItem = ( itemId: number ) => {
468
- const currentIds = Array.isArray( value ) ? value : [ value ];
469
- const newIds = currentIds.filter( ( id ) => id !== itemId );
470
- onChangeControl( newIds.length ? newIds : undefined );
471
- };
497
+ const removeItem = useCallback(
498
+ ( itemId: number ) => {
499
+ const currentIds = Array.isArray( value ) ? value : [ value ];
500
+ const newIds = currentIds.filter( ( id ) => id !== itemId );
501
+ // Mark as touched to immediately show any validation error.
502
+ setIsTouched( true );
503
+ onChangeControl( newIds.length ? newIds : undefined );
504
+ },
505
+ [ value, onChangeControl ]
506
+ );
472
507
  const onFilesDrop = useCallback(
473
508
  ( files: File[], _replacementId?: number ) => {
474
509
  uploadMedia( {
@@ -560,57 +595,132 @@ export default function MediaEdit< Item >( {
560
595
  items.push( ...blobItems );
561
596
  return items;
562
597
  }, [ attachments, replacementId, blobs ] );
598
+ useEffect( () => {
599
+ if ( ! isTouched ) {
600
+ return;
601
+ }
602
+ const input = validityTargetRef.current;
603
+ if ( ! input ) {
604
+ return;
605
+ }
606
+
607
+ if ( validity ) {
608
+ const customValidityResult = validity?.custom;
609
+ setCustomValidity( customValidityResult );
610
+
611
+ // Set custom validity on hidden input for HTML5 form validation.
612
+ if ( customValidityResult?.type === 'invalid' ) {
613
+ input.setCustomValidity(
614
+ customValidityResult.message || __( 'Invalid' )
615
+ );
616
+ } else {
617
+ input.setCustomValidity( '' ); // Clear validity
618
+ }
619
+ } else {
620
+ // Clear any previous validation.
621
+ input.setCustomValidity( '' );
622
+ setCustomValidity( undefined );
623
+ }
624
+ }, [ isTouched, field.isValid, validity ] );
625
+ const onBlur = useCallback(
626
+ ( event: React.FocusEvent< HTMLElement > ) => {
627
+ if ( isTouched ) {
628
+ return;
629
+ }
630
+ if (
631
+ ! event.relatedTarget ||
632
+ ! event.currentTarget.contains( event.relatedTarget )
633
+ ) {
634
+ setIsTouched( true );
635
+ }
636
+ },
637
+ [ isTouched ]
638
+ );
563
639
  return (
564
- <fieldset className="fields__media-edit" data-field-id={ field.id }>
565
- <ConditionalMediaUpload
566
- onSelect={ ( selectedMedia: any ) => {
567
- if ( multiple ) {
568
- const newIds = Array.isArray( selectedMedia )
569
- ? selectedMedia.map( ( m: any ) => m.id )
570
- : [ selectedMedia.id ];
571
- onChangeControl( newIds );
572
- } else {
573
- onChangeControl( selectedMedia.id );
574
- }
575
- } }
576
- allowedTypes={ allowedTypes }
577
- value={ value }
578
- multiple={ multiple }
579
- title={ field.label }
580
- render={ ( { open }: any ) => {
581
- const AttachmentsComponent = isExpanded
582
- ? ExpandedMediaEditAttachments
583
- : CompactMediaEditAttachments;
584
- return (
585
- <VStack spacing={ 2 }>
586
- { field.label &&
587
- ( hideLabelFromVision ? (
588
- <VisuallyHidden as="legend">
589
- { field.label }
590
- </VisuallyHidden>
591
- ) : (
592
- <BaseControl.VisualLabel as="legend">
593
- { field.label }
594
- </BaseControl.VisualLabel>
595
- ) ) }
596
- <AttachmentsComponent
597
- allItems={ allItems }
598
- addButtonLabel={ addButtonLabel }
599
- multiple={ multiple }
600
- removeItem={ removeItem }
601
- open={ open }
602
- onFilesDrop={ onFilesDrop }
603
- isUploading={ !! blobs.length }
604
- />
605
- { field.description && (
606
- <Text variant="muted">
607
- { field.description }
608
- </Text>
609
- ) }
610
- </VStack>
611
- );
612
- } }
613
- />
614
- </fieldset>
640
+ <div onBlur={ onBlur }>
641
+ <fieldset className="fields__media-edit" data-field-id={ field.id }>
642
+ <ConditionalMediaUpload
643
+ onSelect={ ( selectedMedia: any ) => {
644
+ if ( multiple ) {
645
+ const newIds = Array.isArray( selectedMedia )
646
+ ? selectedMedia.map( ( m: any ) => m.id )
647
+ : [ selectedMedia.id ];
648
+ onChangeControl( newIds );
649
+ } else {
650
+ onChangeControl( selectedMedia.id );
651
+ }
652
+ } }
653
+ allowedTypes={ allowedTypes }
654
+ value={ value }
655
+ multiple={ multiple }
656
+ title={ field.label }
657
+ render={ ( { open }: any ) => {
658
+ const AttachmentsComponent = isExpanded
659
+ ? ExpandedMediaEditAttachments
660
+ : CompactMediaEditAttachments;
661
+ return (
662
+ <VStack spacing={ 2 }>
663
+ { field.label &&
664
+ ( hideLabelFromVision ? (
665
+ <VisuallyHidden as="legend">
666
+ { field.label }
667
+ </VisuallyHidden>
668
+ ) : (
669
+ <BaseControl.VisualLabel as="legend">
670
+ { field.label }
671
+ </BaseControl.VisualLabel>
672
+ ) ) }
673
+ <AttachmentsComponent
674
+ allItems={ allItems }
675
+ addButtonLabel={ addButtonLabel }
676
+ multiple={ multiple }
677
+ removeItem={ removeItem }
678
+ open={ open }
679
+ onFilesDrop={ onFilesDrop }
680
+ isUploading={ !! blobs.length }
681
+ />
682
+ { field.description && (
683
+ <Text variant="muted">
684
+ { field.description }
685
+ </Text>
686
+ ) }
687
+ </VStack>
688
+ );
689
+ } }
690
+ />
691
+ </fieldset>
692
+ { /* Visually hidden text input for validation. */ }
693
+ <VisuallyHidden>
694
+ <input
695
+ type="text"
696
+ ref={ validityTargetRef }
697
+ value={ value ?? '' }
698
+ tabIndex={ -1 }
699
+ aria-hidden="true"
700
+ onChange={ () => {} }
701
+ />
702
+ </VisuallyHidden>
703
+ { customValidity && (
704
+ <div aria-live="polite">
705
+ <p
706
+ className={ clsx(
707
+ 'components-validated-control__indicator',
708
+ {
709
+ 'is-invalid': customValidity.type === 'invalid',
710
+ 'is-valid': customValidity.type === 'valid',
711
+ }
712
+ ) }
713
+ >
714
+ <Icon
715
+ className="components-validated-control__indicator-icon"
716
+ icon={ errorIcon }
717
+ size={ 16 }
718
+ fill="currentColor"
719
+ />
720
+ { customValidity.message }
721
+ </p>
722
+ </div>
723
+ ) }
724
+ </div>
615
725
  );
616
726
  }
@@ -1,34 +1,15 @@
1
1
  @use "@wordpress/base-styles/colors" as *;
2
2
  @use "@wordpress/base-styles/variables" as *;
3
3
 
4
- .dataviews-view-grid__media,
5
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media,
6
- .dataviews-view-list__media-wrapper {
7
- .fields-controls__featured-image-image,
8
- .fields-controls__featured-image-placeholder {
9
- width: 100%;
10
- height: 100%;
11
- display: block;
12
- border-radius: $radius-medium;
13
- }
14
-
15
- .fields-controls__featured-image-placeholder {
16
- box-shadow: none;
17
- background: $gray-100;
18
- }
19
- }
20
-
21
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media {
22
- .fields-controls__featured-image-image,
23
- .fields-controls__featured-image-placeholder {
24
- width: 32px;
25
- height: 32px;
26
- }
4
+ .fields-controls__featured-image-image,
5
+ .fields-controls__featured-image-placeholder {
6
+ width: 100%;
7
+ height: 100%;
8
+ display: block;
9
+ border-radius: $radius-medium;
27
10
  }
28
11
 
29
- .dataforms-layouts-panel__field-control {
30
- .fields-controls__featured-image-image {
31
- width: 16px;
32
- height: 16px;
33
- }
12
+ .fields-controls__featured-image-placeholder {
13
+ box-shadow: none;
14
+ background: $gray-100;
34
15
  }
package/src/types.ts CHANGED
@@ -142,7 +142,7 @@ export type CoreDataError = { message?: string; code?: string };
142
142
  export interface MediaEditProps< Item >
143
143
  extends Pick<
144
144
  DataFormControlProps< Item >,
145
- 'data' | 'field' | 'onChange' | 'hideLabelFromVision'
145
+ 'data' | 'field' | 'onChange' | 'hideLabelFromVision' | 'validity'
146
146
  > {
147
147
  /**
148
148
  * Array of allowed media types (e.g., ['image', 'video']).