自定义 useBlockProps

问题描述 投票:0回答:1

我正在制作一个自定义块来插入视频。我使用 BorderControl 组件添加了一些样式选项。

使用组件选择的选项默认应用于编辑器中的块,而不应用 useBlockProps:

return (
    <></>
);

查看视频截图:

https://youtu.be/g5s8eBBIeOM

也就是说,我不需要使用…useBlockProps。古腾堡似乎自动将这些属性应用到根元素。

如果我尝试将 useBlockProps 应用于我选择的元素,我会得到属性的重复项。一个位于默认应用的元素上,另一个位于所选元素上。我正在像这样应用 useBlockProps 。

return (
    <div {...useBlockProps()}></div>
);

查看视频截图:

https://youtu.be/nin8bYEZRn4

默认属性始终呈现,我无法自定义它们的位置。是否可以删除 BlockProps 的默认渲染并使用我自己的自定义?

块.json:

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,
};

编辑.jsx:

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}
          />
        )
      )}
    </>
  );
};
wordpress wordpress-gutenberg gutenberg-blocks
1个回答
0
投票

出现该问题的原因是该块在内部使用了

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>
        )
      )}
    </>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.