@wordpress/block-editor
Version:
162 lines (161 loc) • 5.37 kB
JavaScript
// packages/block-editor/src/components/content-only-controls/rich-text/index.js
import { BaseControl, useBaseControlProps } from "@wordpress/components";
import { useMergeRefs } from "@wordpress/compose";
import { useRegistry } from "@wordpress/data";
import { useRef, useState } from "@wordpress/element";
import {
__unstableUseRichText as useRichText,
removeFormat
} from "@wordpress/rich-text";
import { useFormatTypes } from "../../rich-text/use-format-types";
import { getAllowedFormats } from "../../rich-text/utils";
import { useEventListeners } from "../../rich-text/event-listeners";
import FormatEdit from "../../rich-text/format-edit";
import { keyboardShortcutContext, inputEventContext } from "../../rich-text";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
function RichTextControl({
data,
field,
hideLabelFromVision,
onChange,
config = {}
}) {
const registry = useRegistry();
const attrValue = field.getValue({ item: data });
const fieldConfig = field.config || {};
const { clientId } = config;
const updateAttributes = (html) => {
const mappedChanges = field.setValue({ item: data, value: html });
onChange(mappedChanges);
};
const [selection, setSelection] = useState({
start: void 0,
end: void 0
});
const [isSelected, setIsSelected] = useState(false);
const anchorRef = useRef();
const inputEvents = useRef(/* @__PURE__ */ new Set());
const keyboardShortcuts = useRef(/* @__PURE__ */ new Set());
const adjustedAllowedFormats = getAllowedFormats({
allowedFormats: fieldConfig?.allowedFormats,
disableFormats: fieldConfig?.disableFormats
});
const {
formatTypes,
prepareHandlers,
valueHandlers,
changeHandlers,
dependencies
} = useFormatTypes({
clientId,
identifier: field.id,
allowedFormats: adjustedAllowedFormats,
withoutInteractiveFormatting: fieldConfig?.withoutInteractiveFormatting,
disableNoneEssentialFormatting: true
});
function addEditorOnlyFormats(value2) {
return valueHandlers.reduce(
(accumulator, fn) => fn(accumulator, value2.text),
value2.formats
);
}
function removeEditorOnlyFormats(value2) {
formatTypes.forEach((formatType) => {
if (formatType.__experimentalCreatePrepareEditableTree) {
value2 = removeFormat(
value2,
formatType.name,
0,
value2.text.length
);
}
});
return value2.formats;
}
function addInvisibleFormats(value2) {
return prepareHandlers.reduce(
(accumulator, fn) => fn(accumulator, value2.text),
value2.formats
);
}
function onFocus() {
anchorRef.current?.focus();
}
const {
value,
getValue,
onChange: onRichTextChange,
ref: richTextRef
} = useRichText({
value: attrValue,
onChange(html, { __unstableFormats, __unstableText }) {
updateAttributes(html);
Object.values(changeHandlers).forEach((changeHandler) => {
changeHandler(__unstableFormats, __unstableText);
});
},
selectionStart: selection.start,
selectionEnd: selection.end,
onSelectionChange: (start, end) => setSelection({ start, end }),
__unstableIsSelected: isSelected,
preserveWhiteSpace: !!fieldConfig?.preserveWhiteSpace,
placeholder: fieldConfig?.placeholder,
__unstableDisableFormats: fieldConfig?.disableFormats,
__unstableDependencies: dependencies,
__unstableAfterParse: addEditorOnlyFormats,
__unstableBeforeSerialize: removeEditorOnlyFormats,
__unstableAddInvisibleFormats: addInvisibleFormats
});
const { baseControlProps, controlProps } = useBaseControlProps({
hideLabelFromVision: hideLabelFromVision ?? field.hideLabelFromVision,
label: field.label
});
return /* @__PURE__ */ jsxs(Fragment, { children: [
isSelected && /* @__PURE__ */ jsx(keyboardShortcutContext.Provider, { value: keyboardShortcuts, children: /* @__PURE__ */ jsx(inputEventContext.Provider, { value: inputEvents, children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
FormatEdit,
{
value,
onChange: onRichTextChange,
onFocus,
formatTypes,
forwardedRef: anchorRef,
isVisible: false
}
) }) }) }),
/* @__PURE__ */ jsx(BaseControl, { __nextHasNoMarginBottom: true, ...baseControlProps, children: /* @__PURE__ */ jsx(
"div",
{
className: "block-editor-content-only-controls__rich-text",
role: "textbox",
"aria-multiline": !fieldConfig?.disableLineBreaks,
ref: useMergeRefs([
richTextRef,
useEventListeners({
registry,
getValue,
onChange: onRichTextChange,
formatTypes,
selectionChange: setSelection,
isSelected,
disableFormats: fieldConfig?.disableFormats,
value,
tagName: "div",
removeEditorOnlyFormats,
disableLineBreaks: fieldConfig?.disableLineBreaks,
keyboardShortcuts,
inputEvents
}),
anchorRef
]),
onFocus: () => setIsSelected(true),
onBlur: () => setIsSelected(false),
contentEditable: true,
...controlProps
}
) })
] });
}
export {
RichTextControl as default
};
//# sourceMappingURL=index.js.map