Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1847,6 +1847,12 @@
"markdown_source": "../packages/list-reusable-blocks/README.md",
"parent": "packages"
},
{
"title": "@wordpress/media-fields",
"slug": "packages-media-fields",
"markdown_source": "../packages/media-fields/README.md",
"parent": "packages"
},
{
"title": "@wordpress/media-utils",
"slug": "packages-media-utils",
Expand Down
28 changes: 28 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions packages/media-fields/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Media Fields

This package provides reusable field definitions for displaying and editing media attachment properties in WordPress DataViews. It's primarily intended for internal use within Gutenberg and may change significantly between releases.

## Usage

### Available Fields

This package exports field definitions for common media attachment properties:

- `altTextField` - Alternative text for images
- `captionField` - Media caption text
- `descriptionField` - Detailed description
- `filenameField` - File name (read-only)
- `filesizeField` - File size with human-readable formatting
- `mediaDimensionsField` - Image dimensions (width × height)
- `mediaThumbnailField` - Thumbnail preview
- `mimeTypeField` - MIME type display

### Using Media Fields in DataViews

```jsx
import {
altTextField,
captionField,
filesizeField,
} from '@wordpress/media-fields';
import { DataViews } from '@wordpress/dataviews';

const fields = [
altTextField,
captionField,
filesizeField,
];

export function MyMediaLibrary( { items } ) {
return (
<DataViews
data={ items }
fields={ fields }
view={ view }
onChangeView={ setView }
/>
);
}
```

## Contributing to this package

This package is part of the Gutenberg project. To find out more about contributing to this package or Gutenberg as a whole, please read the project's main [contributor guide](https://github.com/WordPress/gutenberg/tree/HEAD/CONTRIBUTING.md).

<br /><br /><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>
60 changes: 60 additions & 0 deletions packages/media-fields/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "@wordpress/media-fields",
"version": "0.1.0",
"description": "Reusable field definitions for displaying and editing media attachment properties in WordPress.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"keywords": [
"wordpress",
"gutenberg",
"media",
"fields",
"dataviews"
],
"homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/media-fields/README.md",
"repository": {
"type": "git",
"url": "https://github.com/WordPress/gutenberg.git",
"directory": "packages/media-fields"
},
"bugs": {
"url": "https://github.com/WordPress/gutenberg/issues"
},
"engines": {
"node": ">=18.12.0",
"npm": ">=8.19.2"
},
"main": "build/index.js",
"module": "build-module/index.js",
"exports": {
".": {
"types": "./build-types/index.d.ts",
"import": "./build-module/index.js",
"require": "./build/index.js"
},
"./package.json": "./package.json"
},
"react-native": "src/index",
"types": "build-types",
"sideEffects": [
"build-style/**",
"src/**/*.scss"
],
"dependencies": {
"@wordpress/components": "file:../components",
"@wordpress/core-data": "file:../core-data",
"@wordpress/data": "file:../data",
"@wordpress/dataviews": "file:../dataviews",
"@wordpress/element": "file:../element",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/primitives": "file:../primitives",
"@wordpress/url": "file:../url"
},
"peerDependencies": {
"react": "^18.0.0"
},
"publishConfig": {
"access": "public"
}
}
30 changes: 30 additions & 0 deletions packages/media-fields/src/alt_text/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { TextareaControl } from '@wordpress/components';
import type { Field } from '@wordpress/dataviews';
import type { Attachment, Updatable } from '@wordpress/core-data';

const altTextField: Partial< Field< Updatable< Attachment > > > = {
id: 'alt_text',
type: 'text',
label: __( 'Alt text' ),
isVisible: ( item ) => item?.media_type === 'image',
render: ( { item } ) => item?.alt_text || '-',
Edit: ( { field, onChange, data } ) => {
return (
<TextareaControl
label={ field.label }
value={ data.alt_text || '' }
onChange={ ( value ) => onChange( { alt_text: value } ) }
rows={ 2 }
__nextHasNoMarginBottom
/>
);
},
enableSorting: false,
filterBy: false,
};

export default altTextField;
35 changes: 35 additions & 0 deletions packages/media-fields/src/caption/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { TextareaControl } from '@wordpress/components';
import type { Attachment, Updatable } from '@wordpress/core-data';
import type { Field } from '@wordpress/dataviews';

/**
* Internal dependencies
*/
import { getRawContent } from '../utils/get-raw-content';

const captionField: Partial< Field< Updatable< Attachment > > > = {
id: 'caption',
type: 'text',
label: __( 'Caption' ),
getValue: ( { item } ) => getRawContent( item?.caption ),
render: ( { item } ) => getRawContent( item?.caption ) || '-',
Edit: ( { field, onChange, data } ) => {
return (
<TextareaControl
label={ field.label }
value={ getRawContent( data.caption ) || '' }
onChange={ ( value ) => onChange( { caption: value } ) }
rows={ 2 }
__nextHasNoMarginBottom
/>
);
},
enableSorting: false,
filterBy: false,
};

export default captionField;
37 changes: 37 additions & 0 deletions packages/media-fields/src/description/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { TextareaControl } from '@wordpress/components';
import type { Attachment, Updatable } from '@wordpress/core-data';
import type { Field } from '@wordpress/dataviews';

/**
* Internal dependencies
*/
import { getRawContent } from '../utils/get-raw-content';

const descriptionField: Partial< Field< Updatable< Attachment > > > = {
id: 'description',
type: 'text',
label: __( 'Description' ),
getValue: ( { item } ) => getRawContent( item?.description ),
render: ( { item } ) => (
<div>{ getRawContent( item?.description ) || '-' }</div>
),
Edit: ( { field, onChange, data } ) => {
return (
<TextareaControl
label={ field.label }
value={ getRawContent( data.description ) || '' }
onChange={ ( value ) => onChange( { description: value } ) }
rows={ 5 }
__nextHasNoMarginBottom
/>
);
},
enableSorting: false,
filterBy: false,
};

export default descriptionField;
26 changes: 26 additions & 0 deletions packages/media-fields/src/filename/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { getFilename } from '@wordpress/url';
import type { Field } from '@wordpress/dataviews';

/**
* Internal dependencies
*/
import type { MediaItem } from '../types';
import FileNameView from './view';

const filenameField: Partial< Field< MediaItem > > = {
id: 'filename',
type: 'text',
label: __( 'File name' ),
getValue: ( { item }: { item: MediaItem } ) =>
getFilename( item?.source_url || '' ),
render: FileNameView,
enableSorting: false,
filterBy: false,
readOnly: true,
};

export default filenameField;
39 changes: 39 additions & 0 deletions packages/media-fields/src/filename/view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* WordPress dependencies
*/
import {
Tooltip,
__experimentalTruncate as Truncate,
} from '@wordpress/components';
import { useMemo } from '@wordpress/element';
import { getFilename } from '@wordpress/url';
import type { DataViewRenderFieldProps } from '@wordpress/dataviews';
/**
* Internal dependencies
*/
import type { MediaItem } from '../types';

// Hard-coded truncate length to match the available area in the media sidebar.
// Longer file names will be truncated and wrapped in a tooltip showing the full name.
const TRUNCATE_LENGTH = 15;

export default function FileNameView( {
item,
}: DataViewRenderFieldProps< MediaItem > ) {
const fileName = useMemo(
() => ( item?.source_url ? getFilename( item.source_url ) : null ),
[ item?.source_url ]
);

if ( ! fileName ) {
return '';
}

return fileName.length > TRUNCATE_LENGTH ? (
<Tooltip text={ fileName }>
<Truncate>{ fileName }</Truncate>
</Tooltip>
) : (
<>{ fileName }</>
);
}
Loading
Loading