@wordpress/media-fields 0.2.1-next.ba3aee3a2.0 → 0.3.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.
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // packages/media-fields/src/author/index.tsx
31
+ var author_exports = {};
32
+ __export(author_exports, {
33
+ default: () => author_default
34
+ });
35
+ module.exports = __toCommonJS(author_exports);
36
+ var import_i18n = require("@wordpress/i18n");
37
+ var import_data = require("@wordpress/data");
38
+ var import_core_data = require("@wordpress/core-data");
39
+ var import_view = __toESM(require("./view.cjs"));
40
+ var authorField = {
41
+ label: (0, import_i18n.__)("Author"),
42
+ id: "author",
43
+ type: "integer",
44
+ getElements: async () => {
45
+ const authors = await (0, import_data.resolveSelect)(import_core_data.store).getEntityRecords(
46
+ "root",
47
+ "user",
48
+ {
49
+ per_page: -1
50
+ }
51
+ ) ?? [];
52
+ return authors.map(({ id, name }) => ({
53
+ value: id,
54
+ label: name
55
+ }));
56
+ },
57
+ render: import_view.default,
58
+ sort: (a, b, direction) => {
59
+ const nameA = a._embedded?.author?.[0]?.name || "";
60
+ const nameB = b._embedded?.author?.[0]?.name || "";
61
+ return direction === "asc" ? nameA.localeCompare(nameB) : nameB.localeCompare(nameA);
62
+ },
63
+ filterBy: {
64
+ operators: ["isAny", "isNone"]
65
+ },
66
+ readOnly: true
67
+ };
68
+ var author_default = authorField;
69
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/author/index.tsx"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { Field } from '@wordpress/dataviews';\nimport { __ } from '@wordpress/i18n';\nimport { resolveSelect } from '@wordpress/data';\nimport { store as coreDataStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport type { MediaItem } from '../types';\nimport AuthorView from './view';\n\ninterface Author {\n\tid: number;\n\tname: string;\n}\n\nconst authorField: Partial< Field< MediaItem > > = {\n\tlabel: __( 'Author' ),\n\tid: 'author',\n\ttype: 'integer',\n\tgetElements: async () => {\n\t\tconst authors: Author[] =\n\t\t\t( await resolveSelect( coreDataStore ).getEntityRecords(\n\t\t\t\t'root',\n\t\t\t\t'user',\n\t\t\t\t{\n\t\t\t\t\tper_page: -1,\n\t\t\t\t}\n\t\t\t) ) ?? [];\n\t\treturn authors.map( ( { id, name } ) => ( {\n\t\t\tvalue: id,\n\t\t\tlabel: name,\n\t\t} ) );\n\t},\n\trender: AuthorView,\n\tsort: ( a, b, direction ) => {\n\t\tconst nameA = a._embedded?.author?.[ 0 ]?.name || '';\n\t\tconst nameB = b._embedded?.author?.[ 0 ]?.name || '';\n\n\t\treturn direction === 'asc'\n\t\t\t? nameA.localeCompare( nameB )\n\t\t\t: nameB.localeCompare( nameA );\n\t},\n\tfilterBy: {\n\t\toperators: [ 'isAny', 'isNone' ],\n\t},\n\treadOnly: true,\n};\n\nexport default authorField;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,kBAAmB;AACnB,kBAA8B;AAC9B,uBAAuC;AAMvC,kBAAuB;AAOvB,IAAM,cAA6C;AAAA,EAClD,WAAO,gBAAI,QAAS;AAAA,EACpB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa,YAAY;AACxB,UAAM,UACH,UAAM,2BAAe,iBAAAA,KAAc,EAAE;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,QACC,UAAU;AAAA,MACX;AAAA,IACD,KAAO,CAAC;AACT,WAAO,QAAQ,IAAK,CAAE,EAAE,IAAI,KAAK,OAAS;AAAA,MACzC,OAAO;AAAA,MACP,OAAO;AAAA,IACR,EAAI;AAAA,EACL;AAAA,EACA,QAAQ,YAAAC;AAAA,EACR,MAAM,CAAE,GAAG,GAAG,cAAe;AAC5B,UAAM,QAAQ,EAAE,WAAW,SAAU,CAAE,GAAG,QAAQ;AAClD,UAAM,QAAQ,EAAE,WAAW,SAAU,CAAE,GAAG,QAAQ;AAElD,WAAO,cAAc,QAClB,MAAM,cAAe,KAAM,IAC3B,MAAM,cAAe,KAAM;AAAA,EAC/B;AAAA,EACA,UAAU;AAAA,IACT,WAAW,CAAE,SAAS,QAAS;AAAA,EAChC;AAAA,EACA,UAAU;AACX;AAEA,IAAO,iBAAQ;",
6
+ "names": ["coreDataStore", "AuthorView"]
7
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // packages/media-fields/src/author/view.tsx
31
+ var view_exports = {};
32
+ __export(view_exports, {
33
+ default: () => AuthorView
34
+ });
35
+ module.exports = __toCommonJS(view_exports);
36
+ var import_clsx = __toESM(require("clsx"));
37
+ var import_i18n = require("@wordpress/i18n");
38
+ var import_element = require("@wordpress/element");
39
+ var import_icons = require("@wordpress/icons");
40
+ var import_components = require("@wordpress/components");
41
+ var import_jsx_runtime = require("react/jsx-runtime");
42
+ function AuthorView({
43
+ item
44
+ }) {
45
+ const author = item?._embedded?.author?.[0];
46
+ const text = author?.name;
47
+ const imageUrl = author?.avatar_urls?.[48];
48
+ const [loadingState, setLoadingState] = (0, import_element.useState)("loading");
49
+ (0, import_element.useEffect)(() => {
50
+ setLoadingState("loading");
51
+ }, [imageUrl]);
52
+ const imgRef = (0, import_element.useCallback)((img) => {
53
+ if (img?.complete) {
54
+ setLoadingState("instant");
55
+ }
56
+ }, []);
57
+ const handleLoad = () => {
58
+ if (loadingState === "loading") {
59
+ setLoadingState("loaded");
60
+ }
61
+ };
62
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalHStack, { alignment: "left", spacing: 0, children: [
63
+ !!imageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
64
+ "div",
65
+ {
66
+ className: (0, import_clsx.default)("media-author-field__avatar", {
67
+ "is-loading": loadingState === "loading",
68
+ "is-loaded": loadingState === "loaded"
69
+ }),
70
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
71
+ "img",
72
+ {
73
+ ref: imgRef,
74
+ onLoad: handleLoad,
75
+ alt: (0, import_i18n.__)("Author avatar"),
76
+ src: imageUrl
77
+ }
78
+ )
79
+ }
80
+ ),
81
+ !imageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "media-author-field__icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Icon, { icon: import_icons.commentAuthorAvatar }) }),
82
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "media-author-field__name", children: text })
83
+ ] });
84
+ }
85
+ //# sourceMappingURL=view.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/author/view.tsx"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { useState, useCallback, useEffect } from '@wordpress/element';\nimport { commentAuthorAvatar as authorIcon } from '@wordpress/icons';\nimport { __experimentalHStack as HStack, Icon } from '@wordpress/components';\nimport type { DataViewRenderFieldProps } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport type { MediaItem } from '../types';\n\nexport default function AuthorView( {\n\titem,\n}: DataViewRenderFieldProps< MediaItem > ) {\n\tconst author = item?._embedded?.author?.[ 0 ];\n\tconst text = author?.name;\n\tconst imageUrl = author?.avatar_urls?.[ 48 ];\n\n\t/*\n\t * Use three states to avoid fade-in animation for cached images:\n\t * 'instant' = image already cached, 'loading' = waiting, 'loaded' = just finished.\n\t */\n\tconst [ loadingState, setLoadingState ] = useState<\n\t\t'instant' | 'loading' | 'loaded'\n\t>( 'loading' );\n\n\tuseEffect( () => {\n\t\tsetLoadingState( 'loading' );\n\t}, [ imageUrl ] );\n\n\tconst imgRef = useCallback( ( img: HTMLImageElement | null ) => {\n\t\tif ( img?.complete ) {\n\t\t\tsetLoadingState( 'instant' );\n\t\t}\n\t}, [] );\n\n\tconst handleLoad = () => {\n\t\tif ( loadingState === 'loading' ) {\n\t\t\tsetLoadingState( 'loaded' );\n\t\t}\n\t};\n\n\treturn (\n\t\t<HStack alignment=\"left\" spacing={ 0 }>\n\t\t\t{ !! imageUrl && (\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx( 'media-author-field__avatar', {\n\t\t\t\t\t\t'is-loading': loadingState === 'loading',\n\t\t\t\t\t\t'is-loaded': loadingState === 'loaded',\n\t\t\t\t\t} ) }\n\t\t\t\t>\n\t\t\t\t\t<img\n\t\t\t\t\t\tref={ imgRef }\n\t\t\t\t\t\tonLoad={ handleLoad }\n\t\t\t\t\t\talt={ __( 'Author avatar' ) }\n\t\t\t\t\t\tsrc={ imageUrl }\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t{ ! imageUrl && (\n\t\t\t\t<div className=\"media-author-field__icon\">\n\t\t\t\t\t<Icon icon={ authorIcon } />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<span className=\"media-author-field__name\">{ text }</span>\n\t\t</HStack>\n\t);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAiB;AAKjB,kBAAmB;AACnB,qBAAiD;AACjD,mBAAkD;AAClD,wBAAqD;AAwCnD;AAhCa,SAAR,WAA6B;AAAA,EACnC;AACD,GAA2C;AAC1C,QAAM,SAAS,MAAM,WAAW,SAAU,CAAE;AAC5C,QAAM,OAAO,QAAQ;AACrB,QAAM,WAAW,QAAQ,cAAe,EAAG;AAM3C,QAAM,CAAE,cAAc,eAAgB,QAAI,yBAEvC,SAAU;AAEb,gCAAW,MAAM;AAChB,oBAAiB,SAAU;AAAA,EAC5B,GAAG,CAAE,QAAS,CAAE;AAEhB,QAAM,aAAS,4BAAa,CAAE,QAAkC;AAC/D,QAAK,KAAK,UAAW;AACpB,sBAAiB,SAAU;AAAA,IAC5B;AAAA,EACD,GAAG,CAAC,CAAE;AAEN,QAAM,aAAa,MAAM;AACxB,QAAK,iBAAiB,WAAY;AACjC,sBAAiB,QAAS;AAAA,IAC3B;AAAA,EACD;AAEA,SACC,6CAAC,kBAAAA,sBAAA,EAAO,WAAU,QAAO,SAAU,GAChC;AAAA,KAAC,CAAE,YACJ;AAAA,MAAC;AAAA;AAAA,QACA,eAAY,YAAAC,SAAM,8BAA8B;AAAA,UAC/C,cAAc,iBAAiB;AAAA,UAC/B,aAAa,iBAAiB;AAAA,QAC/B,CAAE;AAAA,QAEF;AAAA,UAAC;AAAA;AAAA,YACA,KAAM;AAAA,YACN,QAAS;AAAA,YACT,SAAM,gBAAI,eAAgB;AAAA,YAC1B,KAAM;AAAA;AAAA,QACP;AAAA;AAAA,IACD;AAAA,IAEC,CAAE,YACH,4CAAC,SAAI,WAAU,4BACd,sDAAC,0BAAK,MAAO,aAAAC,qBAAa,GAC3B;AAAA,IAED,4CAAC,UAAK,WAAU,4BAA6B,gBAAM;AAAA,KACpD;AAEF;",
6
+ "names": ["HStack", "clsx", "authorIcon"]
7
+ }
package/build/index.cjs CHANGED
@@ -32,6 +32,7 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  altTextField: () => import_alt_text.default,
34
34
  attachedToField: () => import_attached_to.default,
35
+ authorField: () => import_author.default,
35
36
  captionField: () => import_caption.default,
36
37
  dateAddedField: () => import_date_added.default,
37
38
  dateModifiedField: () => import_date_modified.default,
@@ -45,6 +46,7 @@ __export(index_exports, {
45
46
  module.exports = __toCommonJS(index_exports);
46
47
  var import_alt_text = __toESM(require("./alt_text/index.cjs"));
47
48
  var import_attached_to = __toESM(require("./attached_to/index.cjs"));
49
+ var import_author = __toESM(require("./author/index.cjs"));
48
50
  var import_caption = __toESM(require("./caption/index.cjs"));
49
51
  var import_date_added = __toESM(require("./date_added/index.cjs"));
50
52
  var import_date_modified = __toESM(require("./date_modified/index.cjs"));
@@ -58,6 +60,7 @@ var import_mime_type = __toESM(require("./mime_type/index.cjs"));
58
60
  0 && (module.exports = {
59
61
  altTextField,
60
62
  attachedToField,
63
+ authorField,
61
64
  captionField,
62
65
  dateAddedField,
63
66
  dateModifiedField,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export { default as altTextField } from './alt_text';\nexport { default as attachedToField } from './attached_to';\nexport { default as captionField } from './caption';\nexport { default as dateAddedField } from './date_added';\nexport { default as dateModifiedField } from './date_modified';\nexport { default as descriptionField } from './description';\nexport { default as filenameField } from './filename';\nexport { default as filesizeField } from './filesize';\nexport { default as mediaDimensionsField } from './media_dimensions';\nexport { default as mediaThumbnailField } from './media_thumbnail';\nexport { default as mimeTypeField } from './mime_type';\n\nexport type {\n\tMediaItem,\n\tMediaKind,\n\tMediaType,\n\tMediaItemUpdatable,\n} from './types';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAwC;AACxC,yBAA2C;AAC3C,qBAAwC;AACxC,wBAA0C;AAC1C,2BAA6C;AAC7C,yBAA4C;AAC5C,sBAAyC;AACzC,sBAAyC;AACzC,8BAAgD;AAChD,6BAA+C;AAC/C,uBAAyC;",
4
+ "sourcesContent": ["export { default as altTextField } from './alt_text';\nexport { default as attachedToField } from './attached_to';\nexport { default as authorField } from './author';\nexport { default as captionField } from './caption';\nexport { default as dateAddedField } from './date_added';\nexport { default as dateModifiedField } from './date_modified';\nexport { default as descriptionField } from './description';\nexport { default as filenameField } from './filename';\nexport { default as filesizeField } from './filesize';\nexport { default as mediaDimensionsField } from './media_dimensions';\nexport { default as mediaThumbnailField } from './media_thumbnail';\nexport { default as mimeTypeField } from './mime_type';\n\nexport type {\n\tMediaItem,\n\tMediaKind,\n\tMediaType,\n\tMediaItemUpdatable,\n} from './types';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAwC;AACxC,yBAA2C;AAC3C,oBAAuC;AACvC,qBAAwC;AACxC,wBAA0C;AAC1C,2BAA6C;AAC7C,yBAA4C;AAC5C,sBAAyC;AACzC,sBAAyC;AACzC,8BAAgD;AAChD,6BAA+C;AAC/C,uBAAyC;",
6
6
  "names": []
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 { Attachment, Updatable, Post } from '@wordpress/core-data';\n\nexport type MediaKind = 'image' | 'video' | 'audio' | 'application';\n\nexport interface MediaType {\n\ttype: MediaKind;\n\tlabel: string;\n\ticon: JSX.Element;\n}\n\n// TODO: Update the Attachment type separately.\nexport interface MediaItem extends Attachment< 'edit' > {\n\t// featured_media is not in the Attachment type. See https://github.com/WordPress/gutenberg/blob/trunk/packages/core-data/src/entity-types/attachment.ts#L10\n\tfeatured_media: number;\n\t_embedded?: {\n\t\t// TODO: Include wp:attached-to properly, and backport PHP changes from wordpress-develop to support this.\n\t\t'wp:attached-to'?: Post[] | Partial< Post >[];\n\t};\n}\n\nexport type MediaItemUpdatable = Updatable< Attachment >;\n"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { Attachment, Updatable, Post, User } from '@wordpress/core-data';\n\nexport type MediaKind = 'image' | 'video' | 'audio' | 'application';\n\nexport interface MediaType {\n\ttype: MediaKind;\n\tlabel: string;\n\ticon: JSX.Element;\n}\n\n// TODO: Update the Attachment type separately.\nexport interface MediaItem extends Attachment< 'edit' > {\n\t// featured_media is not in the Attachment type. See https://github.com/WordPress/gutenberg/blob/trunk/packages/core-data/src/entity-types/attachment.ts#L10\n\tfeatured_media: number;\n\t_embedded?: {\n\t\t// TODO: Include wp:attached-to properly, and backport PHP changes from wordpress-develop to support this.\n\t\t'wp:attached-to'?: Post[] | Partial< Post >[];\n\t\tauthor?: User[] | Partial< User >[];\n\t};\n}\n\nexport type MediaItemUpdatable = Updatable< Attachment >;\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,38 @@
1
+ // packages/media-fields/src/author/index.tsx
2
+ import { __ } from "@wordpress/i18n";
3
+ import { resolveSelect } from "@wordpress/data";
4
+ import { store as coreDataStore } from "@wordpress/core-data";
5
+ import AuthorView from "./view.mjs";
6
+ var authorField = {
7
+ label: __("Author"),
8
+ id: "author",
9
+ type: "integer",
10
+ getElements: async () => {
11
+ const authors = await resolveSelect(coreDataStore).getEntityRecords(
12
+ "root",
13
+ "user",
14
+ {
15
+ per_page: -1
16
+ }
17
+ ) ?? [];
18
+ return authors.map(({ id, name }) => ({
19
+ value: id,
20
+ label: name
21
+ }));
22
+ },
23
+ render: AuthorView,
24
+ sort: (a, b, direction) => {
25
+ const nameA = a._embedded?.author?.[0]?.name || "";
26
+ const nameB = b._embedded?.author?.[0]?.name || "";
27
+ return direction === "asc" ? nameA.localeCompare(nameB) : nameB.localeCompare(nameA);
28
+ },
29
+ filterBy: {
30
+ operators: ["isAny", "isNone"]
31
+ },
32
+ readOnly: true
33
+ };
34
+ var author_default = authorField;
35
+ export {
36
+ author_default as default
37
+ };
38
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/author/index.tsx"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { Field } from '@wordpress/dataviews';\nimport { __ } from '@wordpress/i18n';\nimport { resolveSelect } from '@wordpress/data';\nimport { store as coreDataStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport type { MediaItem } from '../types';\nimport AuthorView from './view';\n\ninterface Author {\n\tid: number;\n\tname: string;\n}\n\nconst authorField: Partial< Field< MediaItem > > = {\n\tlabel: __( 'Author' ),\n\tid: 'author',\n\ttype: 'integer',\n\tgetElements: async () => {\n\t\tconst authors: Author[] =\n\t\t\t( await resolveSelect( coreDataStore ).getEntityRecords(\n\t\t\t\t'root',\n\t\t\t\t'user',\n\t\t\t\t{\n\t\t\t\t\tper_page: -1,\n\t\t\t\t}\n\t\t\t) ) ?? [];\n\t\treturn authors.map( ( { id, name } ) => ( {\n\t\t\tvalue: id,\n\t\t\tlabel: name,\n\t\t} ) );\n\t},\n\trender: AuthorView,\n\tsort: ( a, b, direction ) => {\n\t\tconst nameA = a._embedded?.author?.[ 0 ]?.name || '';\n\t\tconst nameB = b._embedded?.author?.[ 0 ]?.name || '';\n\n\t\treturn direction === 'asc'\n\t\t\t? nameA.localeCompare( nameB )\n\t\t\t: nameB.localeCompare( nameA );\n\t},\n\tfilterBy: {\n\t\toperators: [ 'isAny', 'isNone' ],\n\t},\n\treadOnly: true,\n};\n\nexport default authorField;\n"],
5
+ "mappings": ";AAIA,SAAS,UAAU;AACnB,SAAS,qBAAqB;AAC9B,SAAS,SAAS,qBAAqB;AAMvC,OAAO,gBAAgB;AAOvB,IAAM,cAA6C;AAAA,EAClD,OAAO,GAAI,QAAS;AAAA,EACpB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa,YAAY;AACxB,UAAM,UACH,MAAM,cAAe,aAAc,EAAE;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,QACC,UAAU;AAAA,MACX;AAAA,IACD,KAAO,CAAC;AACT,WAAO,QAAQ,IAAK,CAAE,EAAE,IAAI,KAAK,OAAS;AAAA,MACzC,OAAO;AAAA,MACP,OAAO;AAAA,IACR,EAAI;AAAA,EACL;AAAA,EACA,QAAQ;AAAA,EACR,MAAM,CAAE,GAAG,GAAG,cAAe;AAC5B,UAAM,QAAQ,EAAE,WAAW,SAAU,CAAE,GAAG,QAAQ;AAClD,UAAM,QAAQ,EAAE,WAAW,SAAU,CAAE,GAAG,QAAQ;AAElD,WAAO,cAAc,QAClB,MAAM,cAAe,KAAM,IAC3B,MAAM,cAAe,KAAM;AAAA,EAC/B;AAAA,EACA,UAAU;AAAA,IACT,WAAW,CAAE,SAAS,QAAS;AAAA,EAChC;AAAA,EACA,UAAU;AACX;AAEA,IAAO,iBAAQ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,54 @@
1
+ // packages/media-fields/src/author/view.tsx
2
+ import clsx from "clsx";
3
+ import { __ } from "@wordpress/i18n";
4
+ import { useState, useCallback, useEffect } from "@wordpress/element";
5
+ import { commentAuthorAvatar as authorIcon } from "@wordpress/icons";
6
+ import { __experimentalHStack as HStack, Icon } from "@wordpress/components";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function AuthorView({
9
+ item
10
+ }) {
11
+ const author = item?._embedded?.author?.[0];
12
+ const text = author?.name;
13
+ const imageUrl = author?.avatar_urls?.[48];
14
+ const [loadingState, setLoadingState] = useState("loading");
15
+ useEffect(() => {
16
+ setLoadingState("loading");
17
+ }, [imageUrl]);
18
+ const imgRef = useCallback((img) => {
19
+ if (img?.complete) {
20
+ setLoadingState("instant");
21
+ }
22
+ }, []);
23
+ const handleLoad = () => {
24
+ if (loadingState === "loading") {
25
+ setLoadingState("loaded");
26
+ }
27
+ };
28
+ return /* @__PURE__ */ jsxs(HStack, { alignment: "left", spacing: 0, children: [
29
+ !!imageUrl && /* @__PURE__ */ jsx(
30
+ "div",
31
+ {
32
+ className: clsx("media-author-field__avatar", {
33
+ "is-loading": loadingState === "loading",
34
+ "is-loaded": loadingState === "loaded"
35
+ }),
36
+ children: /* @__PURE__ */ jsx(
37
+ "img",
38
+ {
39
+ ref: imgRef,
40
+ onLoad: handleLoad,
41
+ alt: __("Author avatar"),
42
+ src: imageUrl
43
+ }
44
+ )
45
+ }
46
+ ),
47
+ !imageUrl && /* @__PURE__ */ jsx("div", { className: "media-author-field__icon", children: /* @__PURE__ */ jsx(Icon, { icon: authorIcon }) }),
48
+ /* @__PURE__ */ jsx("span", { className: "media-author-field__name", children: text })
49
+ ] });
50
+ }
51
+ export {
52
+ AuthorView as default
53
+ };
54
+ //# sourceMappingURL=view.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/author/view.tsx"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { useState, useCallback, useEffect } from '@wordpress/element';\nimport { commentAuthorAvatar as authorIcon } from '@wordpress/icons';\nimport { __experimentalHStack as HStack, Icon } from '@wordpress/components';\nimport type { DataViewRenderFieldProps } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport type { MediaItem } from '../types';\n\nexport default function AuthorView( {\n\titem,\n}: DataViewRenderFieldProps< MediaItem > ) {\n\tconst author = item?._embedded?.author?.[ 0 ];\n\tconst text = author?.name;\n\tconst imageUrl = author?.avatar_urls?.[ 48 ];\n\n\t/*\n\t * Use three states to avoid fade-in animation for cached images:\n\t * 'instant' = image already cached, 'loading' = waiting, 'loaded' = just finished.\n\t */\n\tconst [ loadingState, setLoadingState ] = useState<\n\t\t'instant' | 'loading' | 'loaded'\n\t>( 'loading' );\n\n\tuseEffect( () => {\n\t\tsetLoadingState( 'loading' );\n\t}, [ imageUrl ] );\n\n\tconst imgRef = useCallback( ( img: HTMLImageElement | null ) => {\n\t\tif ( img?.complete ) {\n\t\t\tsetLoadingState( 'instant' );\n\t\t}\n\t}, [] );\n\n\tconst handleLoad = () => {\n\t\tif ( loadingState === 'loading' ) {\n\t\t\tsetLoadingState( 'loaded' );\n\t\t}\n\t};\n\n\treturn (\n\t\t<HStack alignment=\"left\" spacing={ 0 }>\n\t\t\t{ !! imageUrl && (\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx( 'media-author-field__avatar', {\n\t\t\t\t\t\t'is-loading': loadingState === 'loading',\n\t\t\t\t\t\t'is-loaded': loadingState === 'loaded',\n\t\t\t\t\t} ) }\n\t\t\t\t>\n\t\t\t\t\t<img\n\t\t\t\t\t\tref={ imgRef }\n\t\t\t\t\t\tonLoad={ handleLoad }\n\t\t\t\t\t\talt={ __( 'Author avatar' ) }\n\t\t\t\t\t\tsrc={ imageUrl }\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t{ ! imageUrl && (\n\t\t\t\t<div className=\"media-author-field__icon\">\n\t\t\t\t\t<Icon icon={ authorIcon } />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<span className=\"media-author-field__name\">{ text }</span>\n\t\t</HStack>\n\t);\n}\n"],
5
+ "mappings": ";AAGA,OAAO,UAAU;AAKjB,SAAS,UAAU;AACnB,SAAS,UAAU,aAAa,iBAAiB;AACjD,SAAS,uBAAuB,kBAAkB;AAClD,SAAS,wBAAwB,QAAQ,YAAY;AAwCnD,SAQG,KARH;AAhCa,SAAR,WAA6B;AAAA,EACnC;AACD,GAA2C;AAC1C,QAAM,SAAS,MAAM,WAAW,SAAU,CAAE;AAC5C,QAAM,OAAO,QAAQ;AACrB,QAAM,WAAW,QAAQ,cAAe,EAAG;AAM3C,QAAM,CAAE,cAAc,eAAgB,IAAI,SAEvC,SAAU;AAEb,YAAW,MAAM;AAChB,oBAAiB,SAAU;AAAA,EAC5B,GAAG,CAAE,QAAS,CAAE;AAEhB,QAAM,SAAS,YAAa,CAAE,QAAkC;AAC/D,QAAK,KAAK,UAAW;AACpB,sBAAiB,SAAU;AAAA,IAC5B;AAAA,EACD,GAAG,CAAC,CAAE;AAEN,QAAM,aAAa,MAAM;AACxB,QAAK,iBAAiB,WAAY;AACjC,sBAAiB,QAAS;AAAA,IAC3B;AAAA,EACD;AAEA,SACC,qBAAC,UAAO,WAAU,QAAO,SAAU,GAChC;AAAA,KAAC,CAAE,YACJ;AAAA,MAAC;AAAA;AAAA,QACA,WAAY,KAAM,8BAA8B;AAAA,UAC/C,cAAc,iBAAiB;AAAA,UAC/B,aAAa,iBAAiB;AAAA,QAC/B,CAAE;AAAA,QAEF;AAAA,UAAC;AAAA;AAAA,YACA,KAAM;AAAA,YACN,QAAS;AAAA,YACT,KAAM,GAAI,eAAgB;AAAA,YAC1B,KAAM;AAAA;AAAA,QACP;AAAA;AAAA,IACD;AAAA,IAEC,CAAE,YACH,oBAAC,SAAI,WAAU,4BACd,8BAAC,QAAK,MAAO,YAAa,GAC3B;AAAA,IAED,oBAAC,UAAK,WAAU,4BAA6B,gBAAM;AAAA,KACpD;AAEF;",
6
+ "names": []
7
+ }
@@ -1,26 +1,28 @@
1
1
  // packages/media-fields/src/index.ts
2
2
  import { default as default2 } from "./alt_text/index.mjs";
3
3
  import { default as default3 } from "./attached_to/index.mjs";
4
- import { default as default4 } from "./caption/index.mjs";
5
- import { default as default5 } from "./date_added/index.mjs";
6
- import { default as default6 } from "./date_modified/index.mjs";
7
- import { default as default7 } from "./description/index.mjs";
8
- import { default as default8 } from "./filename/index.mjs";
9
- import { default as default9 } from "./filesize/index.mjs";
10
- import { default as default10 } from "./media_dimensions/index.mjs";
11
- import { default as default11 } from "./media_thumbnail/index.mjs";
12
- import { default as default12 } from "./mime_type/index.mjs";
4
+ import { default as default4 } from "./author/index.mjs";
5
+ import { default as default5 } from "./caption/index.mjs";
6
+ import { default as default6 } from "./date_added/index.mjs";
7
+ import { default as default7 } from "./date_modified/index.mjs";
8
+ import { default as default8 } from "./description/index.mjs";
9
+ import { default as default9 } from "./filename/index.mjs";
10
+ import { default as default10 } from "./filesize/index.mjs";
11
+ import { default as default11 } from "./media_dimensions/index.mjs";
12
+ import { default as default12 } from "./media_thumbnail/index.mjs";
13
+ import { default as default13 } from "./mime_type/index.mjs";
13
14
  export {
14
15
  default2 as altTextField,
15
16
  default3 as attachedToField,
16
- default4 as captionField,
17
- default5 as dateAddedField,
18
- default6 as dateModifiedField,
19
- default7 as descriptionField,
20
- default8 as filenameField,
21
- default9 as filesizeField,
22
- default10 as mediaDimensionsField,
23
- default11 as mediaThumbnailField,
24
- default12 as mimeTypeField
17
+ default4 as authorField,
18
+ default5 as captionField,
19
+ default6 as dateAddedField,
20
+ default7 as dateModifiedField,
21
+ default8 as descriptionField,
22
+ default9 as filenameField,
23
+ default10 as filesizeField,
24
+ default11 as mediaDimensionsField,
25
+ default12 as mediaThumbnailField,
26
+ default13 as mimeTypeField
25
27
  };
26
28
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export { default as altTextField } from './alt_text';\nexport { default as attachedToField } from './attached_to';\nexport { default as captionField } from './caption';\nexport { default as dateAddedField } from './date_added';\nexport { default as dateModifiedField } from './date_modified';\nexport { default as descriptionField } from './description';\nexport { default as filenameField } from './filename';\nexport { default as filesizeField } from './filesize';\nexport { default as mediaDimensionsField } from './media_dimensions';\nexport { default as mediaThumbnailField } from './media_thumbnail';\nexport { default as mimeTypeField } from './mime_type';\n\nexport type {\n\tMediaItem,\n\tMediaKind,\n\tMediaType,\n\tMediaItemUpdatable,\n} from './types';\n"],
5
- "mappings": ";AAAA,SAAoB,WAAXA,gBAA+B;AACxC,SAAoB,WAAXA,gBAAkC;AAC3C,SAAoB,WAAXA,gBAA+B;AACxC,SAAoB,WAAXA,gBAAiC;AAC1C,SAAoB,WAAXA,gBAAoC;AAC7C,SAAoB,WAAXA,gBAAmC;AAC5C,SAAoB,WAAXA,gBAAgC;AACzC,SAAoB,WAAXA,gBAAgC;AACzC,SAAoB,WAAXA,iBAAuC;AAChD,SAAoB,WAAXA,iBAAsC;AAC/C,SAAoB,WAAXA,iBAAgC;",
4
+ "sourcesContent": ["export { default as altTextField } from './alt_text';\nexport { default as attachedToField } from './attached_to';\nexport { default as authorField } from './author';\nexport { default as captionField } from './caption';\nexport { default as dateAddedField } from './date_added';\nexport { default as dateModifiedField } from './date_modified';\nexport { default as descriptionField } from './description';\nexport { default as filenameField } from './filename';\nexport { default as filesizeField } from './filesize';\nexport { default as mediaDimensionsField } from './media_dimensions';\nexport { default as mediaThumbnailField } from './media_thumbnail';\nexport { default as mimeTypeField } from './mime_type';\n\nexport type {\n\tMediaItem,\n\tMediaKind,\n\tMediaType,\n\tMediaItemUpdatable,\n} from './types';\n"],
5
+ "mappings": ";AAAA,SAAoB,WAAXA,gBAA+B;AACxC,SAAoB,WAAXA,gBAAkC;AAC3C,SAAoB,WAAXA,gBAA8B;AACvC,SAAoB,WAAXA,gBAA+B;AACxC,SAAoB,WAAXA,gBAAiC;AAC1C,SAAoB,WAAXA,gBAAoC;AAC7C,SAAoB,WAAXA,gBAAmC;AAC5C,SAAoB,WAAXA,gBAAgC;AACzC,SAAoB,WAAXA,iBAAgC;AACzC,SAAoB,WAAXA,iBAAuC;AAChD,SAAoB,WAAXA,iBAAsC;AAC/C,SAAoB,WAAXA,iBAAgC;",
6
6
  "names": ["default"]
7
7
  }
@@ -87,6 +87,50 @@
87
87
  * Creates a checkerboard pattern background to indicate transparency.
88
88
  * @param {String} $size - The size of the squares in the checkerboard pattern. Default is 12px.
89
89
  */
90
+ .media-author-field__avatar {
91
+ flex-shrink: 0;
92
+ overflow: hidden;
93
+ width: 24px;
94
+ height: 24px;
95
+ align-items: center;
96
+ justify-content: right;
97
+ display: flex;
98
+ }
99
+ .media-author-field__avatar img {
100
+ width: 16px;
101
+ height: 16px;
102
+ object-fit: cover;
103
+ opacity: 1;
104
+ border-radius: 100%;
105
+ }
106
+ @media not (prefers-reduced-motion) {
107
+ .media-author-field__avatar.is-loading img, .media-author-field__avatar.is-loaded img {
108
+ transition: opacity 0.1s linear;
109
+ }
110
+ }
111
+ .media-author-field__avatar.is-loading img {
112
+ opacity: 0;
113
+ }
114
+ .media-author-field__avatar.is-loaded img {
115
+ opacity: 1;
116
+ }
117
+
118
+ .media-author-field__icon {
119
+ display: flex;
120
+ flex-shrink: 0;
121
+ width: 24px;
122
+ height: 24px;
123
+ }
124
+ .media-author-field__icon svg {
125
+ margin-right: -4px;
126
+ fill: currentColor;
127
+ }
128
+
129
+ .media-author-field__name {
130
+ text-overflow: ellipsis;
131
+ overflow: hidden;
132
+ }
133
+
90
134
  .dataviews-media-field__media-thumbnail {
91
135
  display: flex;
92
136
  align-items: center;
@@ -87,6 +87,50 @@
87
87
  * Creates a checkerboard pattern background to indicate transparency.
88
88
  * @param {String} $size - The size of the squares in the checkerboard pattern. Default is 12px.
89
89
  */
90
+ .media-author-field__avatar {
91
+ flex-shrink: 0;
92
+ overflow: hidden;
93
+ width: 24px;
94
+ height: 24px;
95
+ align-items: center;
96
+ justify-content: left;
97
+ display: flex;
98
+ }
99
+ .media-author-field__avatar img {
100
+ width: 16px;
101
+ height: 16px;
102
+ object-fit: cover;
103
+ opacity: 1;
104
+ border-radius: 100%;
105
+ }
106
+ @media not (prefers-reduced-motion) {
107
+ .media-author-field__avatar.is-loading img, .media-author-field__avatar.is-loaded img {
108
+ transition: opacity 0.1s linear;
109
+ }
110
+ }
111
+ .media-author-field__avatar.is-loading img {
112
+ opacity: 0;
113
+ }
114
+ .media-author-field__avatar.is-loaded img {
115
+ opacity: 1;
116
+ }
117
+
118
+ .media-author-field__icon {
119
+ display: flex;
120
+ flex-shrink: 0;
121
+ width: 24px;
122
+ height: 24px;
123
+ }
124
+ .media-author-field__icon svg {
125
+ margin-left: -4px;
126
+ fill: currentColor;
127
+ }
128
+
129
+ .media-author-field__name {
130
+ text-overflow: ellipsis;
131
+ overflow: hidden;
132
+ }
133
+
90
134
  .dataviews-media-field__media-thumbnail {
91
135
  display: flex;
92
136
  align-items: center;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import type { Field } from '@wordpress/dataviews';
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+ import type { MediaItem } from '../types';
9
+ declare const authorField: Partial<Field<MediaItem>>;
10
+ export default authorField;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/author/index.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAKlD;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAQ1C,QAAA,MAAM,WAAW,EAAE,OAAO,CAAE,KAAK,CAAE,SAAS,CAAE,CA+B7C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { DataViewRenderFieldProps } from '@wordpress/dataviews';
2
+ /**
3
+ * Internal dependencies
4
+ */
5
+ import type { MediaItem } from '../types';
6
+ export default function AuthorView({ item, }: DataViewRenderFieldProps<MediaItem>): import("react").JSX.Element;
7
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/author/view.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAErE;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,CAAC,OAAO,UAAU,UAAU,CAAE,EACnC,IAAI,GACJ,EAAE,wBAAwB,CAAE,SAAS,CAAE,+BAsDvC"}
@@ -1,5 +1,6 @@
1
1
  export { default as altTextField } from './alt_text';
2
2
  export { default as attachedToField } from './attached_to';
3
+ export { default as authorField } from './author';
3
4
  export { default as captionField } from './caption';
4
5
  export { default as dateAddedField } from './date_added';
5
6
  export { default as dateModifiedField } from './date_modified';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,YAAY,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,kBAAkB,GAClB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,YAAY,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,kBAAkB,GAClB,MAAM,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.story.d.ts","sourceRoot":"","sources":["../../src/stories/index.story.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAwB,MAAM,sBAAsB,CAAC;;;;;AAqBtE,wBAGE;AA6RF,eAAO,MAAM,gBAAgB;uBA7CU;QAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;KAAE;;;;;;;;;;;;;CAyDnE,CAAC;AAEF,eAAO,MAAM,gBAAgB,mCA6C5B,CAAC"}
1
+ {"version":3,"file":"index.story.d.ts","sourceRoot":"","sources":["../../src/stories/index.story.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAwB,MAAM,sBAAsB,CAAC;;;;;AAsBtE,wBAGE;AAoUF,eAAO,MAAM,gBAAgB;uBA9CU;QAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;KAAE;;;;;;;;;;;;;CA0DnE,CAAC;AAEF,eAAO,MAAM,gBAAgB,mCA6C5B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import type { Attachment, Updatable, Post } from '@wordpress/core-data';
4
+ import type { Attachment, Updatable, Post, User } from '@wordpress/core-data';
5
5
  export type MediaKind = 'image' | 'video' | 'audio' | 'application';
6
6
  export interface MediaType {
7
7
  type: MediaKind;
@@ -12,6 +12,7 @@ export interface MediaItem extends Attachment<'edit'> {
12
12
  featured_media: number;
13
13
  _embedded?: {
14
14
  'wp:attached-to'?: Post[] | Partial<Post>[];
15
+ author?: User[] | Partial<User>[];
15
16
  };
16
17
  }
17
18
  export type MediaItemUpdatable = Updatable<Attachment>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpE,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC;CAClB;AAGD,MAAM,WAAW,SAAU,SAAQ,UAAU,CAAE,MAAM,CAAE;IAEtD,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE;QAEX,gBAAgB,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,CAAE,IAAI,CAAE,EAAE,CAAC;KAC9C,CAAC;CACF;AAED,MAAM,MAAM,kBAAkB,GAAG,SAAS,CAAE,UAAU,CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE9E,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpE,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC;CAClB;AAGD,MAAM,WAAW,SAAU,SAAQ,UAAU,CAAE,MAAM,CAAE;IAEtD,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE;QAEX,gBAAgB,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,CAAE,IAAI,CAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,CAAE,IAAI,CAAE,EAAE,CAAC;KACpC,CAAC;CACF;AAED,MAAM,MAAM,kBAAkB,GAAG,SAAS,CAAE,UAAU,CAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/media-fields",
3
- "version": "0.2.1-next.ba3aee3a2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Reusable field definitions for displaying and editing media attachment properties in WordPress.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -49,18 +49,19 @@
49
49
  "src/**/*.scss"
50
50
  ],
51
51
  "dependencies": {
52
- "@wordpress/base-styles": "^6.13.2-next.ba3aee3a2.0",
53
- "@wordpress/components": "^32.0.1-next.ba3aee3a2.0",
54
- "@wordpress/compose": "^7.37.1-next.ba3aee3a2.0",
55
- "@wordpress/core-data": "^7.37.1-next.ba3aee3a2.0",
56
- "@wordpress/data": "^10.37.1-next.ba3aee3a2.0",
57
- "@wordpress/dataviews": "^11.2.1-next.ba3aee3a2.0",
58
- "@wordpress/date": "^5.37.2-next.ba3aee3a2.0",
59
- "@wordpress/element": "^6.37.1-next.ba3aee3a2.0",
60
- "@wordpress/i18n": "^6.10.1-next.ba3aee3a2.0",
61
- "@wordpress/icons": "^11.4.1-next.ba3aee3a2.0",
62
- "@wordpress/primitives": "^4.37.1-next.ba3aee3a2.0",
63
- "@wordpress/url": "^4.37.1-next.ba3aee3a2.0"
52
+ "@wordpress/base-styles": "^6.14.0",
53
+ "@wordpress/components": "^32.0.0",
54
+ "@wordpress/compose": "^7.38.0",
55
+ "@wordpress/core-data": "^7.38.0",
56
+ "@wordpress/data": "^10.38.0",
57
+ "@wordpress/dataviews": "^11.2.0",
58
+ "@wordpress/date": "^5.38.0",
59
+ "@wordpress/element": "^6.38.0",
60
+ "@wordpress/i18n": "^6.11.0",
61
+ "@wordpress/icons": "^11.5.0",
62
+ "@wordpress/primitives": "^4.38.0",
63
+ "@wordpress/url": "^4.38.0",
64
+ "clsx": "2.1.1"
64
65
  },
65
66
  "devDependencies": {
66
67
  "@testing-library/jest-dom": "^6.6.3",
@@ -72,5 +73,5 @@
72
73
  "publishConfig": {
73
74
  "access": "public"
74
75
  },
75
- "gitHead": "67d2e486fcd40c753591cf911ca0659132f519ca"
76
+ "gitHead": "50c4c0f51e4797c217946ce42adfaa5eb026f33f"
76
77
  }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import type { Field } from '@wordpress/dataviews';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { resolveSelect } from '@wordpress/data';
7
+ import { store as coreDataStore } from '@wordpress/core-data';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import type { MediaItem } from '../types';
13
+ import AuthorView from './view';
14
+
15
+ interface Author {
16
+ id: number;
17
+ name: string;
18
+ }
19
+
20
+ const authorField: Partial< Field< MediaItem > > = {
21
+ label: __( 'Author' ),
22
+ id: 'author',
23
+ type: 'integer',
24
+ getElements: async () => {
25
+ const authors: Author[] =
26
+ ( await resolveSelect( coreDataStore ).getEntityRecords(
27
+ 'root',
28
+ 'user',
29
+ {
30
+ per_page: -1,
31
+ }
32
+ ) ) ?? [];
33
+ return authors.map( ( { id, name } ) => ( {
34
+ value: id,
35
+ label: name,
36
+ } ) );
37
+ },
38
+ render: AuthorView,
39
+ sort: ( a, b, direction ) => {
40
+ const nameA = a._embedded?.author?.[ 0 ]?.name || '';
41
+ const nameB = b._embedded?.author?.[ 0 ]?.name || '';
42
+
43
+ return direction === 'asc'
44
+ ? nameA.localeCompare( nameB )
45
+ : nameB.localeCompare( nameA );
46
+ },
47
+ filterBy: {
48
+ operators: [ 'isAny', 'isNone' ],
49
+ },
50
+ readOnly: true,
51
+ };
52
+
53
+ export default authorField;
@@ -0,0 +1,58 @@
1
+ @use "@wordpress/base-styles/mixins" as *;
2
+ @use "@wordpress/base-styles/variables" as *;
3
+
4
+ .media-author-field__avatar {
5
+ flex-shrink: 0;
6
+ overflow: hidden;
7
+ width: $grid-unit-30;
8
+ height: $grid-unit-30;
9
+ align-items: center;
10
+ justify-content: left;
11
+ display: flex;
12
+
13
+ img {
14
+ width: $grid-unit-20;
15
+ height: $grid-unit-20;
16
+ object-fit: cover;
17
+ opacity: 1;
18
+ border-radius: 100%;
19
+ }
20
+
21
+ &.is-loading,
22
+ &.is-loaded {
23
+ img {
24
+ @media not (prefers-reduced-motion) {
25
+ transition: opacity 0.1s linear;
26
+ }
27
+ }
28
+ }
29
+
30
+ &.is-loading {
31
+ img {
32
+ opacity: 0;
33
+ }
34
+ }
35
+
36
+ &.is-loaded {
37
+ img {
38
+ opacity: 1;
39
+ }
40
+ }
41
+ }
42
+
43
+ .media-author-field__icon {
44
+ display: flex;
45
+ flex-shrink: 0;
46
+ width: $grid-unit-30;
47
+ height: $grid-unit-30;
48
+
49
+ svg {
50
+ margin-left: -$grid-unit-05;
51
+ fill: currentColor;
52
+ }
53
+ }
54
+
55
+ .media-author-field__name {
56
+ text-overflow: ellipsis;
57
+ overflow: hidden;
58
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { __ } from '@wordpress/i18n';
10
+ import { useState, useCallback, useEffect } from '@wordpress/element';
11
+ import { commentAuthorAvatar as authorIcon } from '@wordpress/icons';
12
+ import { __experimentalHStack as HStack, Icon } from '@wordpress/components';
13
+ import type { DataViewRenderFieldProps } from '@wordpress/dataviews';
14
+
15
+ /**
16
+ * Internal dependencies
17
+ */
18
+ import type { MediaItem } from '../types';
19
+
20
+ export default function AuthorView( {
21
+ item,
22
+ }: DataViewRenderFieldProps< MediaItem > ) {
23
+ const author = item?._embedded?.author?.[ 0 ];
24
+ const text = author?.name;
25
+ const imageUrl = author?.avatar_urls?.[ 48 ];
26
+
27
+ /*
28
+ * Use three states to avoid fade-in animation for cached images:
29
+ * 'instant' = image already cached, 'loading' = waiting, 'loaded' = just finished.
30
+ */
31
+ const [ loadingState, setLoadingState ] = useState<
32
+ 'instant' | 'loading' | 'loaded'
33
+ >( 'loading' );
34
+
35
+ useEffect( () => {
36
+ setLoadingState( 'loading' );
37
+ }, [ imageUrl ] );
38
+
39
+ const imgRef = useCallback( ( img: HTMLImageElement | null ) => {
40
+ if ( img?.complete ) {
41
+ setLoadingState( 'instant' );
42
+ }
43
+ }, [] );
44
+
45
+ const handleLoad = () => {
46
+ if ( loadingState === 'loading' ) {
47
+ setLoadingState( 'loaded' );
48
+ }
49
+ };
50
+
51
+ return (
52
+ <HStack alignment="left" spacing={ 0 }>
53
+ { !! imageUrl && (
54
+ <div
55
+ className={ clsx( 'media-author-field__avatar', {
56
+ 'is-loading': loadingState === 'loading',
57
+ 'is-loaded': loadingState === 'loaded',
58
+ } ) }
59
+ >
60
+ <img
61
+ ref={ imgRef }
62
+ onLoad={ handleLoad }
63
+ alt={ __( 'Author avatar' ) }
64
+ src={ imageUrl }
65
+ />
66
+ </div>
67
+ ) }
68
+ { ! imageUrl && (
69
+ <div className="media-author-field__icon">
70
+ <Icon icon={ authorIcon } />
71
+ </div>
72
+ ) }
73
+ <span className="media-author-field__name">{ text }</span>
74
+ </HStack>
75
+ );
76
+ }
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { default as altTextField } from './alt_text';
2
2
  export { default as attachedToField } from './attached_to';
3
+ export { default as authorField } from './author';
3
4
  export { default as captionField } from './caption';
4
5
  export { default as dateAddedField } from './date_added';
5
6
  export { default as dateModifiedField } from './date_modified';
@@ -11,6 +11,7 @@ import type { Field, View } from '@wordpress/dataviews';
11
11
  import {
12
12
  altTextField,
13
13
  attachedToField,
14
+ authorField,
14
15
  captionField,
15
16
  dateAddedField,
16
17
  dateModifiedField,
@@ -109,6 +110,19 @@ const sampleMediaItem: MediaItem = {
109
110
  },
110
111
  },
111
112
  missing_image_sizes: [],
113
+ _embedded: {
114
+ author: [
115
+ {
116
+ id: 1,
117
+ name: 'John Doe',
118
+ avatar_urls: {
119
+ '24': 'https://gravatar.com/avatar/?s=24&d=mm&r=g',
120
+ '48': 'https://gravatar.com/avatar/?s=48&d=mm&r=g',
121
+ '96': 'https://gravatar.com/avatar/?s=96&d=mm&r=g',
122
+ },
123
+ },
124
+ ],
125
+ },
112
126
  };
113
127
 
114
128
  // Sample data for a non-image file (ZIP)
@@ -197,6 +211,17 @@ const sampleMediaItemZip: MediaItem = {
197
211
  featured_media: 0,
198
212
  },
199
213
  ],
214
+ author: [
215
+ {
216
+ id: 1,
217
+ name: 'Jane Smith',
218
+ avatar_urls: {
219
+ '24': 'https://gravatar.com/avatar/?s=24&d=mm&r=g',
220
+ '48': 'https://gravatar.com/avatar/?s=48&d=mm&r=g',
221
+ '96': 'https://gravatar.com/avatar/?s=96&d=mm&r=g',
222
+ },
223
+ },
224
+ ],
200
225
  },
201
226
  };
202
227
 
@@ -249,6 +274,19 @@ const sampleMediaItemBrokenImage: MediaItem = {
249
274
  sizes: {},
250
275
  },
251
276
  missing_image_sizes: [],
277
+ _embedded: {
278
+ author: [
279
+ {
280
+ id: 1,
281
+ name: 'Admin User',
282
+ avatar_urls: {
283
+ '24': 'https://gravatar.com/avatar/?s=24&d=mm&r=g',
284
+ '48': 'https://gravatar.com/avatar/?s=48&d=mm&r=g',
285
+ '96': 'https://gravatar.com/avatar/?s=96&d=mm&r=g',
286
+ },
287
+ },
288
+ ],
289
+ },
252
290
  };
253
291
 
254
292
  // Create a showcase of all media fields.
@@ -257,6 +295,7 @@ const showcaseFields = [
257
295
  filenameField,
258
296
  altTextField,
259
297
  attachedToField,
298
+ authorField,
260
299
  captionField,
261
300
  dateAddedField,
262
301
  dateModifiedField,
@@ -287,6 +326,7 @@ const DataFormsComponent = ( { type }: { type: 'regular' | 'panel' } ) => {
287
326
  'mime_type',
288
327
  'media_dimensions',
289
328
  'filesize',
329
+ 'author',
290
330
  'date',
291
331
  'modified',
292
332
  'attached_to',
package/src/style.scss CHANGED
@@ -1 +1,2 @@
1
+ @use "./author/style.scss" as *;
1
2
  @use "./media_thumbnail/style.scss" as *;
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import type { Attachment, Updatable, Post } from '@wordpress/core-data';
4
+ import type { Attachment, Updatable, Post, User } from '@wordpress/core-data';
5
5
 
6
6
  export type MediaKind = 'image' | 'video' | 'audio' | 'application';
7
7
 
@@ -18,6 +18,7 @@ export interface MediaItem extends Attachment< 'edit' > {
18
18
  _embedded?: {
19
19
  // TODO: Include wp:attached-to properly, and backport PHP changes from wordpress-develop to support this.
20
20
  'wp:attached-to'?: Post[] | Partial< Post >[];
21
+ author?: User[] | Partial< User >[];
21
22
  };
22
23
  }
23
24