UNPKG

@gechiui/block-editor

Version:
197 lines (181 loc) 5.7 kB
import { createElement, Fragment } from "@gechiui/element"; /** * External dependencies */ import { uniqueId, noop } from 'lodash'; /** * GeChiUI dependencies */ import { useState, createRef, renderToString } from '@gechiui/element'; import { __ } from '@gechiui/i18n'; import { speak } from '@gechiui/a11y'; import { FormFileUpload, NavigableMenu, MenuItem, ToolbarButton, Dropdown, withFilters } from '@gechiui/components'; import { withDispatch, useSelect } from '@gechiui/data'; import { DOWN } from '@gechiui/keycodes'; import { compose } from '@gechiui/compose'; import { upload, media as mediaIcon } from '@gechiui/icons'; import { store as noticesStore } from '@gechiui/notices'; /** * Internal dependencies */ import MediaUpload from '../media-upload'; import MediaUploadCheck from '../media-upload/check'; import LinkControl from '../link-control'; import { store as blockEditorStore } from '../../store'; const MediaReplaceFlow = _ref => { let { mediaURL, mediaId, allowedTypes, accept, onSelect, onSelectURL, onFilesUpload = noop, name = __('替换'), createNotice, removeNotice, children } = _ref; const [mediaURLValue, setMediaURLValue] = useState(mediaURL); const mediaUpload = useSelect(select => { return select(blockEditorStore).getSettings().mediaUpload; }, []); const editMediaButtonRef = createRef(); const errorNoticeID = uniqueId('block-editor/media-replace-flow/error-notice/'); const onError = message => { const errorElement = document.createElement('div'); errorElement.innerHTML = renderToString(message); // The default error contains some HTML that, // for example, makes the filename bold. // The notice, by default, accepts strings only and so // we need to remove the html from the error. const renderMsg = errorElement.textContent || errorElement.innerText || ''; // We need to set a timeout for showing the notice // so that VoiceOver and possibly other screen readers // can announce the error afer the toolbar button // regains focus once the upload dialog closes. // Otherwise VO simply skips over the notice and announces // the focused element and the open menu. setTimeout(() => { createNotice('error', renderMsg, { speak: true, id: errorNoticeID, isDismissible: true }); }, 1000); }; const selectMedia = media => { setMediaURLValue(media.url); // Calling `onSelect` after the state update since it might unmount the component. onSelect(media); speak(__('此媒体文件已被替换')); removeNotice(errorNoticeID); }; const selectURL = newURL => { onSelectURL(newURL); }; const uploadFiles = event => { const files = event.target.files; onFilesUpload(files); const setMedia = _ref2 => { let [media] = _ref2; selectMedia(media); }; mediaUpload({ allowedTypes, filesList: files, onFileChange: setMedia, onError }); }; const openOnArrowDown = event => { if (event.keyCode === DOWN) { event.preventDefault(); event.target.click(); } }; const POPOVER_PROPS = { isAlternate: true }; return createElement(Dropdown, { popoverProps: POPOVER_PROPS, contentClassName: "block-editor-media-replace-flow__options", renderToggle: _ref3 => { let { isOpen, onToggle } = _ref3; return createElement(ToolbarButton, { ref: editMediaButtonRef, "aria-expanded": isOpen, "aria-haspopup": "true", onClick: onToggle, onKeyDown: openOnArrowDown }, name); }, renderContent: _ref4 => { let { onClose } = _ref4; return createElement(Fragment, null, createElement(NavigableMenu, { className: "block-editor-media-replace-flow__media-upload-menu" }, createElement(MediaUpload, { value: mediaId, onSelect: media => selectMedia(media), allowedTypes: allowedTypes, render: _ref5 => { let { open } = _ref5; return createElement(MenuItem, { icon: mediaIcon, onClick: open }, __('打开媒体库')); } }), createElement(MediaUploadCheck, null, createElement(FormFileUpload, { onChange: event => { uploadFiles(event, onClose); }, accept: accept, render: _ref6 => { let { openFileDialog } = _ref6; return createElement(MenuItem, { icon: upload, onClick: () => { openFileDialog(); } }, __('上传')); } })), children), onSelectURL && // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions createElement("form", { className: "block-editor-media-flow__url-input" }, createElement("span", { className: "block-editor-media-replace-flow__image-url-label" }, __('当前媒体网址:')), createElement(LinkControl, { value: { url: mediaURLValue }, settings: [], showSuggestions: false, onChange: _ref7 => { let { url } = _ref7; setMediaURLValue(url); selectURL(url); editMediaButtonRef.current.focus(); } }))); } }); }; export default compose([withDispatch(dispatch => { const { createNotice, removeNotice } = dispatch(noticesStore); return { createNotice, removeNotice }; }), withFilters('editor.MediaReplaceFlow')])(MediaReplaceFlow); //# sourceMappingURL=index.js.map