UNPKG

@wordpress/block-library

Version:
254 lines (253 loc) 7.66 kB
// packages/block-library/src/tabs-menu-item/edit.js import clsx from "clsx"; import { __, sprintf } from "@wordpress/i18n"; import { useBlockProps, withColors, store as blockEditorStore, RichText } from "@wordpress/block-editor"; import { useSelect, useDispatch } from "@wordpress/data"; import { decodeEntities } from "@wordpress/html-entities"; import { RawHTML, useRef, useCallback, useState, useEffect, useMemo } from "@wordpress/element"; import slugFromLabel from "../tab/slug-from-label.mjs"; import Controls from "./controls.mjs"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var { requestAnimationFrame, cancelAnimationFrame } = window; function StaticLabel({ label, index }) { if (label) { return /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(RawHTML, { children: decodeEntities(label) }) }); } return /* @__PURE__ */ jsx("span", { children: sprintf( /* translators: %d is the tab index + 1 */ __("Tab %d"), index + 1 ) }); } function Edit({ attributes, setAttributes, context, clientId, activeBackgroundColor, setActiveBackgroundColor, activeTextColor, setActiveTextColor, hoverBackgroundColor, setHoverBackgroundColor, hoverTextColor, setHoverTextColor, __unstableLayoutClassNames: layoutClassNames }) { const tabIndex = context["core/tabs-menu-item-index"] ?? 0; const tabId = context["core/tabs-menu-item-id"] ?? ""; const tabLabel = context["core/tabs-menu-item-label"] ?? ""; const tabClientId = context["core/tabs-menu-item-clientId"] ?? ""; const contextTabsList = context["core/tabs-list"]; const tabsList = useMemo( () => contextTabsList || [], [contextTabsList] ); const activeTabIndex = context["core/tabs-activeTabIndex"] ?? 0; const editorActiveTabIndex = context["core/tabs-editorActiveTabIndex"]; const effectiveActiveIndex = useMemo(() => { return editorActiveTabIndex ?? activeTabIndex; }, [editorActiveTabIndex, activeTabIndex]); const isActiveTab = tabIndex === effectiveActiveIndex; const { __unstableMarkNextChangeAsNotPersistent } = useDispatch(blockEditorStore); const focusRef = useRef(); const labelElementRef = useRef(null); const [isEditing, setIsEditing] = useState(false); const [editingLabel, setEditingLabel] = useState(""); const { tabsClientId, tabsMenuClientId, selectedTabClientId } = useSelect( (select) => { const { getBlockRootClientId, getSelectedBlockClientIds, hasSelectedInnerBlock } = select(blockEditorStore); const _tabsMenuClientId = getBlockRootClientId(clientId); const _tabsClientId = _tabsMenuClientId ? getBlockRootClientId(_tabsMenuClientId) : null; const selectedIds = getSelectedBlockClientIds(); let selectedTab = null; for (const tab of tabsList) { if (selectedIds.includes(tab.clientId) || hasSelectedInnerBlock(tab.clientId, true)) { selectedTab = tab.clientId; break; } } return { tabsClientId: _tabsClientId, tabsMenuClientId: _tabsMenuClientId, selectedTabClientId: selectedTab }; }, [clientId, tabsList] ); const isSelectedTab = tabClientId === selectedTabClientId; const { updateBlockAttributes } = useDispatch(blockEditorStore); const handleLabelChange = useCallback( (newLabel) => { if (tabClientId) { updateBlockAttributes(tabClientId, { label: newLabel, anchor: slugFromLabel(newLabel, tabIndex) }); } }, [updateBlockAttributes, tabClientId, tabIndex] ); const handleTabClick = useCallback( (event) => { event.preventDefault(); if (tabsClientId && tabIndex !== effectiveActiveIndex) { __unstableMarkNextChangeAsNotPersistent(); updateBlockAttributes(tabsClientId, { editorActiveTabIndex: tabIndex }); } if (isEditing) { } }, [ isEditing, tabsClientId, tabIndex, effectiveActiveIndex, updateBlockAttributes, __unstableMarkNextChangeAsNotPersistent ] ); const labelRef = useCallback( (node) => { labelElementRef.current = node; if (node && isEditing) { const animationId = requestAnimationFrame(() => { if (node) { node.focus(); } }); focusRef.current = animationId; } }, [isEditing] ); useEffect(() => { return () => { if (focusRef.current) { cancelAnimationFrame(focusRef.current); } }; }, []); const customColorStyles = useMemo(() => { const styles = {}; const activeBg = activeBackgroundColor?.color || attributes.customActiveBackgroundColor; const activeText = activeTextColor?.color || attributes.customActiveTextColor; const hoverBg = hoverBackgroundColor?.color || attributes.customHoverBackgroundColor; const hoverText = hoverTextColor?.color || attributes.customHoverTextColor; if (activeBg) { styles["--custom-tab-active-color"] = activeBg; } if (activeText) { styles["--custom-tab-active-text-color"] = activeText; } if (hoverBg) { styles["--custom-tab-hover-color"] = hoverBg; } if (hoverText) { styles["--custom-tab-hover-text-color"] = hoverText; } return styles; }, [ activeBackgroundColor?.color, attributes.customActiveBackgroundColor, activeTextColor?.color, attributes.customActiveTextColor, hoverBackgroundColor?.color, attributes.customHoverBackgroundColor, hoverTextColor?.color, attributes.customHoverTextColor ]); const tabPanelId = tabId || `tab-${tabIndex}`; const tabLabelId = `${tabPanelId}--tab`; const blockProps = useBlockProps({ className: clsx(layoutClassNames, { "is-active": isActiveTab, "is-selected": isSelectedTab }), style: customColorStyles, "aria-controls": tabPanelId, "aria-selected": isActiveTab, id: tabLabelId, role: "tab", tabIndex: isActiveTab ? 0 : -1, onClick: handleTabClick, onDoubleClick: () => { setIsEditing(true); setEditingLabel(tabLabel || ""); } }); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( Controls, { ...{ attributes, setAttributes, clientId, tabsClientId, tabClientId, tabIndex, tabsCount: tabsList.length, tabsMenuClientId, activeBackgroundColor, setActiveBackgroundColor, activeTextColor, setActiveTextColor, hoverBackgroundColor, setHoverBackgroundColor, hoverTextColor, setHoverTextColor } } ), /* @__PURE__ */ jsx("div", { ...blockProps, children: isEditing ? /* @__PURE__ */ jsx( RichText, { ref: labelRef, tagName: "span", withoutInteractiveFormatting: true, placeholder: sprintf( /* translators: %d is the tab index + 1 */ __("Tab %d\u2026"), tabIndex + 1 ), value: decodeEntities(editingLabel), onChange: (value) => { setEditingLabel(value); handleLabelChange(value); }, onBlur: () => { setIsEditing(false); } } ) : /* @__PURE__ */ jsx(StaticLabel, { label: tabLabel, index: tabIndex }) }) ] }); } var edit_default = withColors( "activeBackgroundColor", "activeTextColor", "hoverBackgroundColor", "hoverTextColor" )(Edit); export { edit_default as default }; //# sourceMappingURL=edit.mjs.map