@wordpress/block-library
Version:
Block library for the WordPress editor.
629 lines (627 loc) • 23.4 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// packages/block-library/src/site-logo/edit.js
var edit_exports = {};
__export(edit_exports, {
default: () => LogoEdit
});
module.exports = __toCommonJS(edit_exports);
var import_clsx = __toESM(require("clsx"));
var import_blob = require("@wordpress/blob");
var import_element = require("@wordpress/element");
var import_i18n = require("@wordpress/i18n");
var import_components = require("@wordpress/components");
var import_compose = require("@wordpress/compose");
var import_block_editor = require("@wordpress/block-editor");
var import_data = require("@wordpress/data");
var import_core_data = require("@wordpress/core-data");
var import_icons = require("@wordpress/icons");
var import_notices = require("@wordpress/notices");
var import_constants = require("../image/constants");
var import_hooks = require("../utils/hooks");
var import_jsx_runtime = require("react/jsx-runtime");
var ALLOWED_MEDIA_TYPES = ["image"];
var ACCEPT_MEDIA_STRING = "image/*";
var SiteLogo = ({
alt,
attributes: { align, width, height, isLink, linkTarget, shouldSyncIcon },
isSelected,
setAttributes,
setLogo,
logoUrl,
siteUrl,
logoId,
iconId,
setIcon,
canUserEdit
}) => {
const isLargeViewport = (0, import_compose.useViewportMatch)("medium");
const isWideAligned = ["wide", "full"].includes(align);
const isResizable = !isWideAligned && isLargeViewport;
const [{ naturalWidth, naturalHeight }, setNaturalSize] = (0, import_element.useState)({});
const [isEditingImage, setIsEditingImage] = (0, import_element.useState)(false);
const { toggleSelection } = (0, import_data.useDispatch)(import_block_editor.store);
const dropdownMenuProps = (0, import_hooks.useToolsPanelDropdownMenuProps)();
const blockEditingMode = (0, import_block_editor.useBlockEditingMode)();
const isContentOnlyMode = blockEditingMode === "contentOnly";
const { imageEditing, maxWidth, title } = (0, import_data.useSelect)((select) => {
const settings = select(import_block_editor.store).getSettings();
const siteEntities = select(import_core_data.store).getEntityRecord(
"root",
"__unstableBase"
);
return {
title: siteEntities?.name,
imageEditing: settings.imageEditing,
maxWidth: settings.maxWidth
};
}, []);
(0, import_element.useEffect)(() => {
if (shouldSyncIcon && logoId !== iconId) {
setAttributes({ shouldSyncIcon: false });
}
}, []);
(0, import_element.useEffect)(() => {
if (!isSelected) {
setIsEditingImage(false);
}
}, [isSelected]);
function onResizeStart() {
toggleSelection(false);
}
function onResizeStop() {
toggleSelection(true);
}
const img = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"img",
{
className: "custom-logo",
src: logoUrl,
alt,
onLoad: (event) => {
setNaturalSize({
naturalWidth: event.target.naturalWidth,
naturalHeight: event.target.naturalHeight
});
}
}
),
(0, import_blob.isBlobURL)(logoUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Spinner, {})
] });
let imgWrapper = img;
if (isLink) {
imgWrapper = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"a",
{
href: siteUrl,
className: "custom-logo-link",
rel: "home",
title,
onClick: (event) => event.preventDefault(),
children: img
}
);
}
if (!isResizable || !naturalWidth || !naturalHeight) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { width, height }, children: imgWrapper });
}
const defaultWidth = 120;
const currentWidth = width || defaultWidth;
const ratio = naturalWidth / naturalHeight;
const currentHeight = currentWidth / ratio;
const minWidth = naturalWidth < naturalHeight ? import_constants.MIN_SIZE : Math.ceil(import_constants.MIN_SIZE * ratio);
const minHeight = naturalHeight < naturalWidth ? import_constants.MIN_SIZE : Math.ceil(import_constants.MIN_SIZE / ratio);
const maxWidthBuffer = maxWidth * 2.5;
let showRightHandle = false;
let showLeftHandle = false;
if (align === "center") {
showRightHandle = true;
showLeftHandle = true;
} else if ((0, import_i18n.isRTL)()) {
if (align === "left") {
showRightHandle = true;
} else {
showLeftHandle = true;
}
} else {
if (align === "right") {
showLeftHandle = true;
} else {
showRightHandle = true;
}
}
const canEditImage = logoId && naturalWidth && naturalHeight && imageEditing;
const shouldShowCropAndDimensions = !isContentOnlyMode;
let imgEdit;
if (canEditImage && isEditingImage) {
imgEdit = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_block_editor.__experimentalImageEditor,
{
id: logoId,
url: logoUrl,
width: currentWidth,
height: currentHeight,
naturalHeight,
naturalWidth,
onSaveImage: (imageAttributes) => {
setLogo(imageAttributes.id);
},
onFinishEditing: () => {
setIsEditingImage(false);
}
}
);
} else {
imgEdit = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.ResizableBox,
{
size: {
width: currentWidth,
height: currentHeight
},
showHandle: isSelected && shouldShowCropAndDimensions,
minWidth,
maxWidth: maxWidthBuffer,
minHeight,
maxHeight: maxWidthBuffer / ratio,
lockAspectRatio: true,
enable: {
top: false,
right: showRightHandle,
bottom: true,
left: showLeftHandle
},
onResizeStart,
onResizeStop: (event, direction, elt, delta) => {
onResizeStop();
setAttributes({
width: parseInt(currentWidth + delta.width, 10),
height: parseInt(currentHeight + delta.height, 10)
});
},
children: imgWrapper
}
);
}
const shouldUseNewUrl = !window?.__experimentalUseCustomizerSiteLogoUrl;
const siteIconSettingsUrl = shouldUseNewUrl ? siteUrl + "/wp-admin/options-general.php" : siteUrl + "/wp-admin/customize.php?autofocus[section]=title_tagline";
const syncSiteIconHelpText = (0, import_element.createInterpolateElement)(
(0, import_i18n.__)(
"Site Icons are what you see in browser tabs, bookmark bars, and within the WordPress mobile apps. To use a custom icon that is different from your site logo, use the <a>Site Icon settings</a>."
),
{
a: (
// eslint-disable-next-line jsx-a11y/anchor-has-content
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"a",
{
href: siteIconSettingsUrl,
target: "_blank",
rel: "noopener noreferrer"
}
)
)
}
);
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_block_editor.InspectorControls, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
import_components.__experimentalToolsPanel,
{
label: (0, import_i18n.__)("Settings"),
dropdownMenuProps,
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.__experimentalToolsPanelItem,
{
isShownByDefault: true,
hasValue: () => !!width,
label: (0, import_i18n.__)("Image width"),
onDeselect: () => setAttributes({ width: void 0 }),
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.RangeControl,
{
__nextHasNoMarginBottom: true,
__next40pxDefaultSize: true,
label: (0, import_i18n.__)("Image width"),
onChange: (newWidth) => setAttributes({ width: newWidth }),
min: minWidth,
max: maxWidthBuffer,
initialPosition: Math.min(
defaultWidth,
maxWidthBuffer
),
value: width || "",
disabled: !isResizable
}
)
}
),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.__experimentalToolsPanelItem,
{
isShownByDefault: true,
hasValue: () => !isLink,
label: (0, import_i18n.__)("Link image to home"),
onDeselect: () => setAttributes({ isLink: true }),
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.ToggleControl,
{
__nextHasNoMarginBottom: true,
label: (0, import_i18n.__)("Link image to home"),
onChange: () => setAttributes({ isLink: !isLink }),
checked: isLink
}
)
}
),
isLink && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.__experimentalToolsPanelItem,
{
isShownByDefault: true,
hasValue: () => linkTarget === "_blank",
label: (0, import_i18n.__)("Open in new tab"),
onDeselect: () => setAttributes({ linkTarget: "_self" }),
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.ToggleControl,
{
__nextHasNoMarginBottom: true,
label: (0, import_i18n.__)("Open in new tab"),
onChange: (value) => setAttributes({
linkTarget: value ? "_blank" : "_self"
}),
checked: linkTarget === "_blank"
}
)
}
),
canUserEdit && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.__experimentalToolsPanelItem,
{
isShownByDefault: true,
hasValue: () => !!shouldSyncIcon,
label: (0, import_i18n.__)("Use as Site Icon"),
onDeselect: () => {
setAttributes({ shouldSyncIcon: false });
setIcon(void 0);
},
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.ToggleControl,
{
__nextHasNoMarginBottom: true,
label: (0, import_i18n.__)("Use as Site Icon"),
onChange: (value) => {
setAttributes({ shouldSyncIcon: value });
setIcon(value ? logoId : void 0);
},
checked: !!shouldSyncIcon,
help: syncSiteIconHelpText
}
)
}
)
]
}
) }),
canEditImage && !isEditingImage && shouldShowCropAndDimensions && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_block_editor.BlockControls, { group: "block", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.ToolbarButton,
{
onClick: () => setIsEditingImage(true),
icon: import_icons.crop,
label: (0, import_i18n.__)("Crop")
}
) }),
imgEdit
] });
};
function SiteLogoReplaceFlow({ mediaURL, ...mediaReplaceProps }) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_block_editor.MediaReplaceFlow,
{
...mediaReplaceProps,
mediaURL,
allowedTypes: ALLOWED_MEDIA_TYPES,
accept: ACCEPT_MEDIA_STRING
}
);
}
var InspectorLogoPreview = ({ media, itemGroupProps }) => {
const {
alt_text: alt,
source_url: logoUrl,
slug: logoSlug,
media_details: logoMediaDetails
} = media ?? {};
const logoLabel = logoMediaDetails?.sizes?.full?.file || logoSlug;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalItemGroup, { ...itemGroupProps, as: "span", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalHStack, { justify: "flex-start", as: "span", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: logoUrl, alt }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.FlexItem, { as: "span", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.__experimentalTruncate,
{
numberOfLines: 1,
className: "block-library-site-logo__inspector-media-replace-title",
children: logoLabel
}
) })
] }) });
};
function LogoEdit({
attributes,
className,
setAttributes,
isSelected
}) {
const { width, shouldSyncIcon } = attributes;
const {
siteLogoId,
canUserEdit,
url,
siteIconId,
mediaItemData,
isRequestingMediaItem
} = (0, import_data.useSelect)((select) => {
const { canUser, getEntityRecord, getEditedEntityRecord } = select(import_core_data.store);
const _canUserEdit = canUser("update", {
kind: "root",
name: "site"
});
const siteSettings = _canUserEdit ? getEditedEntityRecord("root", "site") : void 0;
const siteData = getEntityRecord("root", "__unstableBase");
const _siteLogoId = _canUserEdit ? siteSettings?.site_logo : siteData?.site_logo;
const _siteIconId = siteSettings?.site_icon;
const mediaItem = _siteLogoId && select(import_core_data.store).getEntityRecord(
"postType",
"attachment",
_siteLogoId,
{
context: "view"
}
);
const _isRequestingMediaItem = !!_siteLogoId && !select(import_core_data.store).hasFinishedResolution("getEntityRecord", [
"postType",
"attachment",
_siteLogoId,
{ context: "view" }
]);
return {
siteLogoId: _siteLogoId,
canUserEdit: _canUserEdit,
url: siteData?.home,
mediaItemData: mediaItem,
isRequestingMediaItem: _isRequestingMediaItem,
siteIconId: _siteIconId
};
}, []);
const { getSettings } = (0, import_data.useSelect)(import_block_editor.store);
const [temporaryURL, setTemporaryURL] = (0, import_element.useState)();
const dropdownMenuProps = (0, import_hooks.useToolsPanelDropdownMenuProps)();
const { editEntityRecord } = (0, import_data.useDispatch)(import_core_data.store);
const setLogo = (newValue, shouldForceSync = false) => {
if (shouldSyncIcon || shouldForceSync) {
setIcon(newValue);
}
editEntityRecord("root", "site", void 0, {
site_logo: newValue
});
};
const setIcon = (newValue) => (
// The new value needs to be `null` to reset the Site Icon.
editEntityRecord("root", "site", void 0, {
site_icon: newValue ?? null
})
);
const { alt_text: alt, source_url: logoUrl } = mediaItemData ?? {};
const onInitialSelectLogo = (media) => {
if (shouldSyncIcon === void 0) {
const shouldForceSync = !siteIconId;
setAttributes({ shouldSyncIcon: shouldForceSync });
onSelectLogo(media, shouldForceSync);
return;
}
onSelectLogo(media);
};
const onSelectLogo = (media, shouldForceSync = false) => {
if (!media) {
return;
}
if (!media.id && media.url) {
setTemporaryURL(media.url);
setLogo(void 0);
return;
}
setLogo(media.id, shouldForceSync);
};
const onRemoveLogo = () => {
setLogo(null);
setAttributes({ width: void 0 });
};
const { createErrorNotice } = (0, import_data.useDispatch)(import_notices.store);
const onUploadError = (message) => {
createErrorNotice(message, { type: "snackbar" });
setTemporaryURL();
};
const onFilesDrop = (filesList) => {
getSettings().mediaUpload({
allowedTypes: ALLOWED_MEDIA_TYPES,
filesList,
onFileChange([image]) {
if ((0, import_blob.isBlobURL)(image?.url)) {
setTemporaryURL(image.url);
return;
}
onInitialSelectLogo(image);
},
onError: onUploadError,
multiple: false
});
};
const mediaReplaceFlowProps = {
mediaURL: logoUrl,
name: !logoUrl ? (0, import_i18n.__)("Choose logo") : (0, import_i18n.__)("Replace"),
onSelect: onSelectLogo,
onError: onUploadError,
onReset: onRemoveLogo
};
const controls = canUserEdit && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_block_editor.BlockControls, { group: "other", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SiteLogoReplaceFlow, { ...mediaReplaceFlowProps }) });
let logoImage;
const isLoading = siteLogoId === void 0 || isRequestingMediaItem;
if (isLoading) {
logoImage = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Spinner, {});
}
(0, import_element.useEffect)(() => {
if (logoUrl && temporaryURL) {
setTemporaryURL();
}
}, [logoUrl, temporaryURL]);
if (!!logoUrl || !!temporaryURL) {
logoImage = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
SiteLogo,
{
alt,
attributes,
className,
isSelected,
setAttributes,
logoUrl: temporaryURL || logoUrl,
setLogo,
logoId: mediaItemData?.id || siteLogoId,
siteUrl: url,
setIcon,
iconId: siteIconId,
canUserEdit
}
),
canUserEdit && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.DropZone, { onFilesDrop })
] });
}
const placeholder = (content) => {
const placeholderClassName = (0, import_clsx.default)(
"block-editor-media-placeholder",
className
);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.Placeholder,
{
className: placeholderClassName,
preview: logoImage,
withIllustration: true,
style: {
width
},
children: content
}
);
};
const classes = (0, import_clsx.default)(className, {
"is-default-size": !width,
"is-transient": temporaryURL
});
const blockProps = (0, import_block_editor.useBlockProps)({ className: classes });
const mediaInspectorPanel = (canUserEdit || logoUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_block_editor.InspectorControls, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.__experimentalToolsPanel,
{
label: (0, import_i18n.__)("Media"),
dropdownMenuProps,
children: !canUserEdit ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
className: "block-library-site-logo__inspector-media-replace-container",
style: { gridColumn: "1 / -1" },
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
InspectorLogoPreview,
{
media: mediaItemData,
itemGroupProps: {
isBordered: true,
className: "block-library-site-logo__inspector-readonly-logo-preview"
}
}
)
}
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.__experimentalToolsPanelItem,
{
hasValue: () => !!logoUrl,
label: (0, import_i18n.__)("Logo"),
isShownByDefault: true,
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "block-library-site-logo__inspector-media-replace-container", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
SiteLogoReplaceFlow,
{
...mediaReplaceFlowProps,
name: !!logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
InspectorLogoPreview,
{
media: mediaItemData
}
) : (0, import_i18n.__)("Choose logo"),
renderToggle: (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Button, { ...props, __next40pxDefaultSize: true, children: temporaryURL ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Spinner, {}) : props.children })
}
),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.DropZone, { onFilesDrop })
] })
}
)
}
) });
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ...blockProps, children: [
controls,
mediaInspectorPanel,
(!!logoUrl || !!temporaryURL) && logoImage,
(isLoading || !temporaryURL && !logoUrl && !canUserEdit) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Placeholder, { className: "site-logo_placeholder", withIllustration: true, children: isLoading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "components-placeholder__preview", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Spinner, {}) }) }),
!isLoading && !temporaryURL && !logoUrl && canUserEdit && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_block_editor.MediaPlaceholder,
{
onSelect: onInitialSelectLogo,
accept: ACCEPT_MEDIA_STRING,
allowedTypes: ALLOWED_MEDIA_TYPES,
onError: onUploadError,
placeholder,
mediaLibraryButton: ({ open }) => {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_components.Button,
{
__next40pxDefaultSize: true,
icon: import_icons.upload,
variant: "primary",
label: (0, import_i18n.__)("Choose logo"),
showTooltip: true,
tooltipPosition: "middle right",
onClick: () => {
open();
}
}
);
}
}
)
] });
}
//# sourceMappingURL=edit.js.map