Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/lexical-playground/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ pre::-webkit-scrollbar-thumb {
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3);
border-radius: 8px;
position: relative;
width: fit-content;
}

.typeahead-popover ul {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ const theme: EditorThemeClasses = {
},
mark: 'PlaygroundEditorTheme__mark',
markOverlap: 'PlaygroundEditorTheme__markOverlap',
menu: {
container: 'typeahead-popover',
item: 'PlaygroundEditorTheme__menuItem',
itemSelected: 'PlaygroundEditorTheme__menuItemSelected',
itemText: 'PlaygroundEditorTheme__menuItemText',
},
paragraph: 'PlaygroundEditorTheme__paragraph',
quote: 'PlaygroundEditorTheme__quote',
specialText: 'PlaygroundEditorTheme__specialText',
Expand Down
44 changes: 39 additions & 5 deletions packages/lexical-react/src/shared/LexicalMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@

import type {JSX} from 'react';

import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import {
type LexicalComposerContextWithEditor,
useLexicalComposerContext,
} from '@lexical/react/LexicalComposerContext';
import {mergeRegister} from '@lexical/utils';
import {
$getSelection,
Expand Down Expand Up @@ -249,16 +252,34 @@ function MenuItem({
onClick,
onMouseEnter,
option,
theme,
}: {
index: number;
isSelected: boolean;
onClick: () => void;
onMouseEnter: () => void;
option: MenuOption;
theme: LexicalComposerContextWithEditor[1]['getTheme'];
}) {
let className = 'item';
const themeClasses = theme();
const menuTheme =
themeClasses != null && themeClasses.menu != null
? themeClasses.menu
: null;
const itemClassName =
menuTheme != null && menuTheme.item != null ? menuTheme.item : 'item';
const itemSelectedClassName =
menuTheme != null && menuTheme.itemSelected != null
? menuTheme.itemSelected
: 'selected';
const itemTextClassName =
menuTheme != null && menuTheme.itemText != null
? menuTheme.itemText
: 'text';

let className = itemClassName;
if (isSelected) {
className += ' selected';
className += ` ${itemSelectedClassName}`;
}
return (
<li
Expand All @@ -272,7 +293,7 @@ function MenuItem({
onMouseEnter={onMouseEnter}
onClick={onClick}>
{option.icon}
<span className="text">{option.title}</span>
<span className={itemTextClassName}>{option.title}</span>
</li>
);
}
Expand Down Expand Up @@ -303,6 +324,7 @@ export function LexicalMenu<TOption extends MenuOption>({
commandPriority?: CommandListenerPriority;
preselectFirstItem?: boolean;
}): JSX.Element | null {
const [, {getTheme}] = useLexicalComposerContext();
const [rawSelectedIndex, setHighlightedIndex] = useState<null | number>(null);
// Clamp highlighted index if options list shrinks
const selectedIndex =
Expand Down Expand Up @@ -352,9 +374,19 @@ export function LexicalMenu<TOption extends MenuOption>({
);

const menuRenderFn = useCallback(() => {
const themeClasses = getTheme();
const menuTheme =
themeClasses != null && themeClasses.menu != null
? themeClasses.menu
: null;
const containerClassName =
menuTheme != null && menuTheme.container != null
? menuTheme.container
: 'typeahead-popover mentions-menu';

return anchorElementRef.current && options.length
? ReactDOM.createPortal(
<div className="typeahead-popover mentions-menu">
<div className={containerClassName}>
<ul>
{options.map((option, i: number) => (
<MenuItem
Expand All @@ -369,6 +401,7 @@ export function LexicalMenu<TOption extends MenuOption>({
}}
key={option.key}
option={option}
theme={getTheme}
/>
))}
</ul>
Expand All @@ -382,6 +415,7 @@ export function LexicalMenu<TOption extends MenuOption>({
selectedIndex,
selectOptionAndCleanUp,
setHighlightedIndex,
getTheme,
]);

useEffect(() => {
Expand Down
6 changes: 6 additions & 0 deletions packages/lexical/flow/Lexical.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,12 @@ export type EditorThemeClasses = {
base?: EditorThemeClassName,
focus?: EditorThemeClassName,
},
menu?: {
container?: EditorThemeClassName,
item?: EditorThemeClassName,
itemSelected?: EditorThemeClassName,
itemText?: EditorThemeClassName,
},
// Handle other generic values
[string]: EditorThemeClassName | {[string]: EditorThemeClassName},
};
Expand Down
6 changes: 6 additions & 0 deletions packages/lexical/src/LexicalEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ export type EditorThemeClasses = {
focus?: EditorThemeClassName;
};
indent?: EditorThemeClassName;
menu?: {
container?: EditorThemeClassName;
item?: EditorThemeClassName;
itemSelected?: EditorThemeClassName;
itemText?: EditorThemeClassName;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
};
Expand Down
Loading