Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
244 lines
7.3 KiB
Plaintext
244 lines
7.3 KiB
Plaintext
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
var react = require('react');
|
|
var jsxRuntime = require('react/jsx-runtime');
|
|
var text = require('@lexical/text');
|
|
var utils = require('@lexical/utils');
|
|
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
|
|
// This workaround is no longer necessary in React 19,
|
|
// but we currently support React >=17.x
|
|
// https://github.com/facebook/react/pull/26395
|
|
const useLayoutEffectImpl = CAN_USE_DOM ? react.useLayoutEffect : react.useEffect;
|
|
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
// Source: https://github.com/gregberge/react-merge-refs/blob/main/src/index.tsx
|
|
|
|
function mergeRefs(...refs) {
|
|
return value => {
|
|
refs.forEach(ref => {
|
|
if (typeof ref === 'function') {
|
|
ref(value);
|
|
} else if (ref != null) {
|
|
ref.current = value;
|
|
}
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
function ContentEditableElementImpl({
|
|
editor,
|
|
ariaActiveDescendant,
|
|
ariaAutoComplete,
|
|
ariaControls,
|
|
ariaDescribedBy,
|
|
ariaErrorMessage,
|
|
ariaExpanded,
|
|
ariaInvalid,
|
|
ariaLabel,
|
|
ariaLabelledBy,
|
|
ariaMultiline,
|
|
ariaOwns,
|
|
ariaRequired,
|
|
autoCapitalize,
|
|
className,
|
|
id,
|
|
role = 'textbox',
|
|
spellCheck = true,
|
|
style,
|
|
tabIndex,
|
|
'data-testid': testid,
|
|
...rest
|
|
}, ref) {
|
|
const [isEditable, setEditable] = react.useState(editor.isEditable());
|
|
const handleRef = react.useCallback(rootElement => {
|
|
// defaultView is required for a root element.
|
|
// In multi-window setups, the defaultView may not exist at certain points.
|
|
if (rootElement && rootElement.ownerDocument && rootElement.ownerDocument.defaultView) {
|
|
editor.setRootElement(rootElement);
|
|
} else {
|
|
editor.setRootElement(null);
|
|
}
|
|
}, [editor]);
|
|
const mergedRefs = react.useMemo(() => mergeRefs(ref, handleRef), [handleRef, ref]);
|
|
useLayoutEffectImpl(() => {
|
|
setEditable(editor.isEditable());
|
|
return editor.registerEditableListener(currentIsEditable => {
|
|
setEditable(currentIsEditable);
|
|
});
|
|
}, [editor]);
|
|
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
"aria-activedescendant": isEditable ? ariaActiveDescendant : undefined,
|
|
"aria-autocomplete": isEditable ? ariaAutoComplete : 'none',
|
|
"aria-controls": isEditable ? ariaControls : undefined,
|
|
"aria-describedby": ariaDescribedBy
|
|
// for compat, only override aria-errormessage if ariaErrorMessage is defined
|
|
,
|
|
...(ariaErrorMessage != null ? {
|
|
'aria-errormessage': ariaErrorMessage
|
|
} : {}),
|
|
"aria-expanded": isEditable && role === 'combobox' ? !!ariaExpanded : undefined
|
|
// for compat, only override aria-invalid if ariaInvalid is defined
|
|
,
|
|
...(ariaInvalid != null ? {
|
|
'aria-invalid': ariaInvalid
|
|
} : {}),
|
|
"aria-label": ariaLabel,
|
|
"aria-labelledby": ariaLabelledBy,
|
|
"aria-multiline": ariaMultiline,
|
|
"aria-owns": isEditable ? ariaOwns : undefined,
|
|
"aria-readonly": isEditable ? undefined : true,
|
|
"aria-required": ariaRequired,
|
|
autoCapitalize: autoCapitalize,
|
|
className: className,
|
|
contentEditable: isEditable,
|
|
"data-testid": testid,
|
|
id: id,
|
|
ref: mergedRefs,
|
|
role: role,
|
|
spellCheck: spellCheck,
|
|
style: style,
|
|
tabIndex: tabIndex,
|
|
...rest
|
|
});
|
|
}
|
|
const ContentEditableElement = /*#__PURE__*/react.forwardRef(ContentEditableElementImpl);
|
|
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
function canShowPlaceholderFromCurrentEditorState(editor) {
|
|
const currentCanShowPlaceholder = editor.getEditorState().read(text.$canShowPlaceholderCurry(editor.isComposing()));
|
|
return currentCanShowPlaceholder;
|
|
}
|
|
function useCanShowPlaceholder(editor) {
|
|
const [canShowPlaceholder, setCanShowPlaceholder] = react.useState(() => canShowPlaceholderFromCurrentEditorState(editor));
|
|
useLayoutEffectImpl(() => {
|
|
function resetCanShowPlaceholder() {
|
|
const currentCanShowPlaceholder = canShowPlaceholderFromCurrentEditorState(editor);
|
|
setCanShowPlaceholder(currentCanShowPlaceholder);
|
|
}
|
|
resetCanShowPlaceholder();
|
|
return utils.mergeRegister(editor.registerUpdateListener(() => {
|
|
resetCanShowPlaceholder();
|
|
}), editor.registerEditableListener(() => {
|
|
resetCanShowPlaceholder();
|
|
}));
|
|
}, [editor]);
|
|
return canShowPlaceholder;
|
|
}
|
|
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
|
|
/**
|
|
* @deprecated This type has been renamed to `ContentEditableProps` to provide a clearer and more descriptive name.
|
|
* For backward compatibility, this type is still exported as `Props`, but it is recommended to migrate to using `ContentEditableProps` instead.
|
|
*
|
|
* @note This alias is maintained for compatibility purposes but may be removed in future versions.
|
|
* Please update your codebase to use `ContentEditableProps` to ensure long-term maintainability.
|
|
*/
|
|
|
|
const ContentEditable = /*#__PURE__*/react.forwardRef(ContentEditableImpl);
|
|
function ContentEditableImpl(props, ref) {
|
|
const {
|
|
placeholder,
|
|
...rest
|
|
} = props;
|
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
children: [/*#__PURE__*/jsxRuntime.jsx(ContentEditableElement, {
|
|
editor: editor,
|
|
...rest,
|
|
ref: ref
|
|
}), placeholder != null && /*#__PURE__*/jsxRuntime.jsx(Placeholder, {
|
|
editor: editor,
|
|
content: placeholder
|
|
})]
|
|
});
|
|
}
|
|
function Placeholder({
|
|
content,
|
|
editor
|
|
}) {
|
|
const showPlaceholder = useCanShowPlaceholder(editor);
|
|
const [isEditable, setEditable] = react.useState(editor.isEditable());
|
|
react.useLayoutEffect(() => {
|
|
setEditable(editor.isEditable());
|
|
return editor.registerEditableListener(currentIsEditable => {
|
|
setEditable(currentIsEditable);
|
|
});
|
|
}, [editor]);
|
|
if (!showPlaceholder) {
|
|
return null;
|
|
}
|
|
let placeholder = null;
|
|
if (typeof content === 'function') {
|
|
placeholder = content(isEditable);
|
|
} else if (content !== null) {
|
|
placeholder = content;
|
|
}
|
|
if (placeholder === null) {
|
|
return null;
|
|
}
|
|
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
"aria-hidden": true,
|
|
children: placeholder
|
|
});
|
|
}
|
|
|
|
exports.ContentEditable = ContentEditable;
|
|
exports.ContentEditableElement = ContentEditableElement;
|