Skip to content

Commit

Permalink
Add: Media field changing ui to Dataviews and content preview field t…
Browse files Browse the repository at this point in the history
…o posts and pages.
  • Loading branch information
jorgefilipecosta authored and ntsekouras committed Dec 17, 2024
1 parent 9cba28a commit 0555cab
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 58 deletions.
252 changes: 206 additions & 46 deletions packages/dataviews/src/components/dataviews-view-config/index.tsx

Large diffs are not rendered by default.

17 changes: 15 additions & 2 deletions packages/dataviews/src/components/dataviews-view-config/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
}

.dataviews-field-control__field:hover,
.dataviews-field-control__field:focus-within {
.dataviews-field-control__field:focus-within,
.dataviews-field-control__field.is-interacting {
.dataviews-field-control__actions {
position: unset;
top: unset;
Expand All @@ -81,6 +82,18 @@
width: $icon-size;
}

.dataviews-field-control__label {
.dataviews-field-control__label-sub-label-container {
flex-grow: 1;
}

.dataviews-field-control__label {
display: block;
}

.dataviews-field-control__sub-label {
margin-top: $grid-unit-10;
margin-bottom: 0;
font-size: 11px;
font-style: normal;
color: $gray-700;
}
5 changes: 5 additions & 0 deletions packages/dataviews/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ export type Field< Item > = {
* Defaults to `item[ field.id ]`.
*/
getValue?: ( args: { item: Item } ) => any;

/**
* True if the field is supposed to be used as a media field.
*/
isMediaField?: boolean;
};

export type NormalizedField< Item > = Field< Item > & {
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ _Parameters_
- _props.post_ `[Object]`: The post object to edit. This is required.
- _props.\_\_unstableTemplate_ `[Object]`: The template object wrapper the edited post. This is optional and can only be used when the post type supports templates (like posts and pages).
- _props.settings_ `[Object]`: The settings object to use for the editor. This is optional and can be used to override the default settings.
- _props.children_ `[Element]`: Children elements for which the BlockEditorProvider context should apply. This is optional.
- _props.children_ `[React.ReactNode]`: Children elements for which the BlockEditorProvider context should apply. This is optional.

_Returns_

Expand Down
16 changes: 8 additions & 8 deletions packages/editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,14 +392,14 @@ export const ExperimentalEditorProvider = withRegistryProvider(
*
* All modification and changes are performed to the `@wordpress/core-data` store.
*
* @param {Object} props The component props.
* @param {Object} [props.post] The post object to edit. This is required.
* @param {Object} [props.__unstableTemplate] The template object wrapper the edited post.
* This is optional and can only be used when the post type supports templates (like posts and pages).
* @param {Object} [props.settings] The settings object to use for the editor.
* This is optional and can be used to override the default settings.
* @param {Element} [props.children] Children elements for which the BlockEditorProvider context should apply.
* This is optional.
* @param {Object} props The component props.
* @param {Object} [props.post] The post object to edit. This is required.
* @param {Object} [props.__unstableTemplate] The template object wrapper the edited post.
* This is optional and can only be used when the post type supports templates (like posts and pages).
* @param {Object} [props.settings] The settings object to use for the editor.
* This is optional and can be used to override the default settings.
* @param {React.ReactNode} [props.children] Children elements for which the BlockEditorProvider context should apply.
* This is optional.
*
* @example
* ```jsx
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import {
BlockPreview,
privateApis as blockEditorPrivateApis,
// @ts-ignore
} from '@wordpress/block-editor';
import type { BasePost } from '@wordpress/fields';
import { useSelect } from '@wordpress/data';
import { useEntityBlockEditor, store as coreStore } from '@wordpress/core-data';

/**
* Internal dependencies
*/
import { EditorProvider } from '../../../components/provider';
import { unlock } from '../../../lock-unlock';
// @ts-ignore
import { store as editorStore } from '../../../store';

const { useGlobalStyle } = unlock( blockEditorPrivateApis );

function ContentPreviewContainer( {
template,
post,
}: {
template: any;
post: any;
} ) {
const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' );
const [ postBlocks ] = useEntityBlockEditor( 'postType', post.type, {
id: post.id,
} );
const [ templateBlocks ] = useEntityBlockEditor(
'postType',
template?.type,
{
id: template?.id,
}
);
const blocks = template && templateBlocks ? templateBlocks : postBlocks;
const isEmpty = ! blocks?.length;
return (
<div
className="editor-fields-content-preview"
style={ {
backgroundColor,
} }
>
{ isEmpty && (
<span className="editor-fields-content-preview__empty">
{ __( 'Empty content' ) }
</span>
) }
{ ! isEmpty && (
<BlockPreview.Async>
<BlockPreview blocks={ blocks } />
</BlockPreview.Async>
) }
</div>
);
}

export default function ContentPreviewView( { item }: { item: BasePost } ) {
const { settings, template } = useSelect(
( select ) => {
const { canUser, getPostType, getTemplateId, getEntityRecord } =
unlock( select( coreStore ) );
const canViewTemplate = canUser( 'read', {
kind: 'postType',
name: 'wp_template',
} );
const _settings = select( editorStore ).getEditorSettings();
// @ts-ignore
const supportsTemplateMode = _settings.supportsTemplateMode;
const isViewable = getPostType( item.type )?.viewable ?? false;

const templateId =
supportsTemplateMode && isViewable && canViewTemplate
? getTemplateId( item.type, item.id )
: null;
return {
settings: _settings,
template: templateId
? getEntityRecord( 'postType', 'wp_template', templateId )
: undefined,
};
},
[ item.type, item.id ]
);
// Wrap everything in a block editor provider to ensure 'styles' that are needed
// for the previews are synced between the site editor store and the block editor store.
// Additionally we need to have the `__experimentalBlockPatterns` setting in order to
// render patterns inside the previews.
// TODO: Same approach is used in the patterns list and it becomes obvious that some of
// the block editor settings are needed in context where we don't have the block editor.
// Explore how we can solve this in a better way.
return (
<EditorProvider
post={ item }
settings={ settings }
__unstableTemplate={ template }
>
<ContentPreviewContainer template={ template } post={ item } />
</EditorProvider>
);
}
22 changes: 22 additions & 0 deletions packages/editor/src/dataviews/fields/content-preview/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* WordPress dependencies
*/
import type { Field } from '@wordpress/dataviews';
import type { BasePost } from '@wordpress/fields';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import ContentPreviewView from './content-preview-view';

const contentPreviewField: Field< BasePost > = {
type: 'text',
id: 'content-preview',
label: __( 'Content preview' ),
render: ContentPreviewView,
enableSorting: false,
isMediaField: true,
};

export default contentPreviewField;
21 changes: 21 additions & 0 deletions packages/editor/src/dataviews/fields/content-preview/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.editor-fields-content-preview {
display: flex;
flex-direction: column;
height: 100%;
border-radius: $radius-medium;

.dataviews-view-table & {
width: 96px;
flex-grow: 0;
}

.block-editor-block-preview__container,
.editor-fields-content-preview__empty {
margin-top: auto;
margin-bottom: auto;
}
}

.editor-fields-content-preview__empty {
text-align: center;
}
2 changes: 2 additions & 0 deletions packages/editor/src/dataviews/store/private-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
* Internal dependencies
*/
import { store as editorStore } from '../../store';
import contentPreviewField from '../fields/content-preview';
import { unlock } from '../../lock-unlock';

export function registerEntityAction< Item >(
Expand Down Expand Up @@ -175,6 +176,7 @@ export const registerPostTypeSchema =
postTypeConfig.supports?.comments && commentStatusField,
templateField,
passwordField,
contentPreviewField,
].filter( Boolean );
if ( postTypeConfig.supports?.title ) {
let _titleField;
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@
@import "./components/table-of-contents/style.scss";
@import "./components/text-editor/style.scss";
@import "./components/visual-editor/style.scss";
@import "./dataviews/fields/content-preview/style.scss";
4 changes: 4 additions & 0 deletions packages/fields/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ npm install @wordpress/fields --save

Author field for BasePost.

### BasePost

Undocumented declaration.

### BasePostWithEmbeddedAuthor

Undocumented declaration.
Expand Down
1 change: 1 addition & 0 deletions packages/fields/src/fields/featured-image/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const featuredImageField: Field< BasePost > = {
Edit: FeaturedImageEdit,
render: FeaturedImageView,
enableSorting: false,
isMediaField: true,
};

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/fields/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './fields';
export * from './actions';
export { default as CreateTemplatePartModal } from './components/create-template-part-modal';
export type { BasePostWithEmbeddedAuthor, PostType } from './types';
export type { BasePostWithEmbeddedAuthor, BasePost, PostType } from './types';

0 comments on commit 0555cab

Please sign in to comment.