我正在制作一个自定义块来插入视频。我使用 BorderControl 组件添加了一些样式选项。
使用组件选择的选项默认应用于编辑器中的块,而不应用 useBlockProps:
return (
<></>
);
查看视频截图:
也就是说,我不需要使用…useBlockProps。古腾堡似乎自动将这些属性应用到根元素。
如果我尝试将 useBlockProps 应用于我选择的元素,我会得到属性的重复项。一个位于默认应用的元素上,另一个位于所选元素上。我正在像这样应用 useBlockProps 。
return (
<div {...useBlockProps()}></div>
);
查看视频截图:
默认属性始终呈现,我无法自定义它们的位置。是否可以删除 BlockProps 的默认渲染并使用我自己的自定义?
export default {
name: `sage/video`,
title: `Video`,
category: `fb`,
icon: CustomIcon,
attributes: {
libraryId: {
type: 'string',
default: '265348',
},
videoId: {
type: 'string',
default: '',
},
thumbnailUrl: {
type: 'string',
default: '',
},
align: {
type: 'string',
default: 'none',
},
autoplay: {
type: 'boolean',
default: false,
},
loop: {
type: 'boolean',
default: false,
},
muted: {
type: 'boolean',
default: false,
},
controls: {
type: 'boolean',
default: true,
},
playsInline: {
type: 'boolean',
default: true,
},
style: {
type: 'object',
default: {
border: {
color: '',
radius: '0px',
style: 'solid',
width: '1px',
},
},
},
},
supports: {
align: ['wide', 'full'],
spacing: {
margin: false,
padding: false,
},
},
edit: Edit,
save: () => null,
};
import {
TextControl,
PanelBody,
ToggleControl,
Button,
ToolbarGroup,
ToolbarButton,
__experimentalBorderControl as BorderControl,
__experimentalUnitControl as UnitControl,
} from '@wordpress/components';
import {
InspectorControls,
BlockControls,
MediaUpload,
MediaUploadCheck,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import PropTypes from 'prop-types';
import { useEffect, useState } from '@wordpress/element';
import VideoPlayer from '../../components/video/VideoPlayer';
import { Eye, Edit3 } from 'react-feather';
const EditVideo = ({ attributes, setAttributes }) => {
const {
videoId,
thumbnailUrl,
autoplay,
loop,
muted,
controls,
playsInline,
libraryId,
style,
} = attributes;
const [isEditing, setIsEditing] = useState(true);
const removeImage = () => {
setAttributes({ thumbnailUrl: '' });
};
const colors = [
{ name: 'Black', color: '#000000' },
{ name: 'White', color: '#FFFFFF' },
// Añade más colores según sea necesario
];
return (
<>
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon={
isEditing ? (
<Eye className="feather-icon" />
) : (
<Edit3 className="feather-icon" />
)
}
label={
isEditing
? __('Switch to Preview', 'sage')
: __('Switch to Edit', 'sage')
}
onClick={() => setIsEditing(!isEditing)}
/>
</ToolbarGroup>
</BlockControls>
<InspectorControls>
<PanelBody title={__('Video Settings', 'sage')}>
<ToggleControl
label={__('Autoplay', 'sage')}
checked={autoplay}
onChange={(value) => setAttributes({ autoplay: value })}
/>
<ToggleControl
label={__('Loop', 'sage')}
checked={loop}
onChange={(value) => setAttributes({ loop: value })}
/>
<ToggleControl
label={__('Muted', 'sage')}
checked={muted}
onChange={(value) => setAttributes({ muted: value })}
/>
<ToggleControl
label={__('Playback Controls', 'sage')}
checked={controls}
onChange={(value) => setAttributes({ controls: value })}
/>
<ToggleControl
label={__('Play Inline', 'sage')}
checked={playsInline}
onChange={(value) => setAttributes({ playsInline: value })}
/>
</PanelBody>
<PanelBody title={__('Style Settings', 'sage')}>
<PanelBody title={__('Style Settings', 'sage')}>
<BorderControl
colors={colors}
label={__('Border', 'sage')}
value={{
color: style.border.color,
style: style.border.style,
width: style.border.width,
radius: style.border.radius,
}}
withSlider={true}
width="100px"
onChange={(newBorder) => {
setAttributes({
style: {
...style,
border: {
color: newBorder.color,
style: newBorder.style,
width: newBorder.width,
radius: newBorder.radius,
},
},
});
}}
/>
<UnitControl
label={__('Border Radius', 'sage')}
value={style.border.radius}
onChange={(newRadius) => {
setAttributes({
style: {
...style,
border: {
...style.border,
radius: newRadius,
},
},
});
}}
/>
</PanelBody>
</PanelBody>
</InspectorControls>
{isEditing ? (
<>
<TextControl
label={__('Video ID', 'sage')}
value={videoId}
onChange={(id) => setAttributes({ videoId: id })}
placeholder={__('Enter Bunny.net video ID...', 'sage')}
className="m-4"
/>
<TextControl
label={__('Library ID', 'sage')}
value={libraryId}
onChange={(id) => setAttributes({ libraryId: id })}
placeholder={__('Leave blank to get default library', 'sage')}
className="m-4"
/>
<MediaUploadCheck>
<MediaUpload
onSelect={(media) => setAttributes({ thumbnailUrl: media.url })}
allowedTypes={['image']}
render={({ open }) => (
<div>
{thumbnailUrl ? (
<div>
<img
src={thumbnailUrl}
alt={__('Thumbnail', 'sage')}
className="block w-60 mx-4 mt-4"
/>
<Button
onClick={open}
variant="secondary"
className="m-4"
>
{__('Change Thumbnail', 'sage')}
</Button>
<Button onClick={removeImage} variant="destructive">
{__('Remove Thumbnail', 'sage')}
</Button>
</div>
) : (
<Button variant="secondary" onClick={open} className="m-4">
{__('Select Thumbnail', 'sage')}
</Button>
)}
</div>
)}
/>
</MediaUploadCheck>
</>
) : (
videoId && (
<VideoPlayer
videoId={videoId}
thumbnailUrl={thumbnailUrl}
autoplay={autoplay}
loop={loop}
muted={muted}
controls={controls}
playsInline={playsInline}
/>
)
)}
</>
);
};
出现该问题的原因是该块在内部使用了
style
属性来设置具有 useBlockProps()
的块的样式。因此,您自己的实现设置了与核心块相同的样式集。
最简单的解决方案是暂时启用过期边境管制。这将为您提供与核心块相同的边框控件,因此您不必在
Edit.jsx
中创建它们。
export default {
name: 'sage/video',
title: 'Video',
category: 'fb',
icon: CustomIcon,
attributes: {
libraryId: {
type: 'string',
default: '265348',
},
videoId: {
type: 'string',
default: '',
},
thumbnailUrl: {
type: 'string',
default: '',
},
align: {
type: 'string',
default: 'none',
},
autoplay: {
type: 'boolean',
default: false,
},
loop: {
type: 'boolean',
default: false,
},
muted: {
type: 'boolean',
default: false,
},
controls: {
type: 'boolean',
default: true,
},
playsInline: {
type: 'boolean',
default: true,
}
},
supports: {
align: ['wide', 'full'],
spacing: {
margin: false,
padding: false,
},
__experimentalBorder: {
color: true,
radius: true,
style: true,
width: true,
__experimentalDefaultControls: {
color: true,
radius: true,
style: true,
width: true,
},
}
},
edit: Edit,
save: () => null
};
import {
TextControl,
PanelBody,
ToggleControl,
Button,
ToolbarGroup,
ToolbarButton,
} from '@wordpress/components';
import {
useBlockProps,
InspectorControls,
BlockControls,
MediaUpload,
MediaUploadCheck,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import PropTypes from 'prop-types';
import { useEffect, useState } from '@wordpress/element';
import VideoPlayer from '../../components/video/VideoPlayer';
import { Eye, Edit3 } from 'react-feather';
const EditVideo = ({ attributes, setAttributes }) => {
const {
videoId,
thumbnailUrl,
autoplay,
loop,
muted,
controls,
playsInline,
libraryId,
style,
} = attributes;
const blockProps = useBlockProps();
const [isEditing, setIsEditing] = useState(true);
const removeImage = () => {
setAttributes({ thumbnailUrl: '' });
};
const colors = [
{ name: 'Black', color: '#000000' },
{ name: 'White', color: '#FFFFFF' },
// Añade más colores según sea necesario
];
return (
<>
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon={
isEditing ? (
<Eye className="feather-icon" />
) : (
<Edit3 className="feather-icon" />
)
}
label={
isEditing
? __('Switch to Preview', 'sage')
: __('Switch to Edit', 'sage')
}
onClick={() => setIsEditing(!isEditing)}
/>
</ToolbarGroup>
</BlockControls>
<InspectorControls>
<PanelBody title={__('Video Settings', 'sage')}>
<ToggleControl
label={__('Autoplay', 'sage')}
checked={autoplay}
onChange={(value) => setAttributes({ autoplay: value })}
/>
<ToggleControl
label={__('Loop', 'sage')}
checked={loop}
onChange={(value) => setAttributes({ loop: value })}
/>
<ToggleControl
label={__('Muted', 'sage')}
checked={muted}
onChange={(value) => setAttributes({ muted: value })}
/>
<ToggleControl
label={__('Playback Controls', 'sage')}
checked={controls}
onChange={(value) => setAttributes({ controls: value })}
/>
<ToggleControl
label={__('Play Inline', 'sage')}
checked={playsInline}
onChange={(value) => setAttributes({ playsInline: value })}
/>
</PanelBody>
</InspectorControls>
{isEditing ? (
<>
<TextControl
label={__('Video ID', 'sage')}
value={videoId}
onChange={(id) => setAttributes({ videoId: id })}
placeholder={__('Enter Bunny.net video ID...', 'sage')}
className="m-4"
/>
<TextControl
label={__('Library ID', 'sage')}
value={libraryId}
onChange={(id) => setAttributes({ libraryId: id })}
placeholder={__('Leave blank to get default library', 'sage')}
className="m-4"
/>
<MediaUploadCheck>
<MediaUpload
onSelect={(media) => setAttributes({ thumbnailUrl: media.url })}
allowedTypes={['image']}
render={({ open }) => (
<div>
{thumbnailUrl ? (
<div>
<img
src={thumbnailUrl}
alt={__('Thumbnail', 'sage')}
className="block w-60 mx-4 mt-4"
/>
<Button
onClick={open}
variant="secondary"
className="m-4"
>
{__('Change Thumbnail', 'sage')}
</Button>
<Button onClick={removeImage} variant="destructive">
{__('Remove Thumbnail', 'sage')}
</Button>
</div>
) : (
<Button variant="secondary" onClick={open} className="m-4">
{__('Select Thumbnail', 'sage')}
</Button>
)}
</div>
)}
/>
</MediaUploadCheck>
</>
) : (
videoId && (
<div {...blockProps}>
<VideoPlayer
videoId={videoId}
thumbnailUrl={thumbnailUrl}
autoplay={autoplay}
loop={loop}
muted={muted}
controls={controls}
playsInline={playsInline}
/>
</div>
)
)}
</>
);
};