Allows commenting outside edit mode when seamless editing is disabled. (#5422)
This commit is contained in:
@@ -18,6 +18,7 @@ import useToasts from "~/hooks/useToasts";
|
||||
import getDividerMenuItems from "../menus/divider";
|
||||
import getFormattingMenuItems from "../menus/formatting";
|
||||
import getImageMenuItems from "../menus/image";
|
||||
import getReadOnlyMenuItems from "../menus/readOnly";
|
||||
import getTableMenuItems from "../menus/table";
|
||||
import getTableColMenuItems from "../menus/tableCol";
|
||||
import getTableRowMenuItems from "../menus/tableRow";
|
||||
@@ -29,6 +30,8 @@ import ToolbarMenu from "./ToolbarMenu";
|
||||
type Props = {
|
||||
rtl: boolean;
|
||||
isTemplate: boolean;
|
||||
readOnly?: boolean;
|
||||
canComment?: boolean;
|
||||
onOpen: () => void;
|
||||
onClose: () => void;
|
||||
onSearchLink?: (term: string) => Promise<SearchResult[]>;
|
||||
@@ -82,25 +85,25 @@ function useIsDragging() {
|
||||
}
|
||||
|
||||
export default function SelectionToolbar(props: Props) {
|
||||
const { onClose, onOpen } = props;
|
||||
const { onClose, readOnly, onOpen } = props;
|
||||
const { view, commands } = useEditor();
|
||||
const { showToast: onShowToast } = useToasts();
|
||||
const dictionary = useDictionary();
|
||||
const menuRef = React.useRef<HTMLDivElement | null>(null);
|
||||
const isActive = useIsActive(view.state);
|
||||
const isDragging = useIsDragging();
|
||||
const previousIsActuve = usePrevious(isActive);
|
||||
const previousIsActive = usePrevious(isActive);
|
||||
const isMobile = useMobile();
|
||||
|
||||
React.useEffect(() => {
|
||||
// Trigger callbacks when the toolbar is opened or closed
|
||||
if (previousIsActuve && !isActive) {
|
||||
if (previousIsActive && !isActive) {
|
||||
onClose();
|
||||
}
|
||||
if (!previousIsActuve && isActive) {
|
||||
if (!previousIsActive && isActive) {
|
||||
onOpen();
|
||||
}
|
||||
}, [isActive, onClose, onOpen, previousIsActuve]);
|
||||
}, [isActive, onClose, onOpen, previousIsActive]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleClickOutside = (ev: MouseEvent): void => {
|
||||
@@ -111,12 +114,11 @@ export default function SelectionToolbar(props: Props) {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isActive || document.activeElement?.tagName === "INPUT") {
|
||||
if (view.dom.contains(ev.target as HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (view.hasFocus()) {
|
||||
if (!isActive || document.activeElement?.tagName === "INPUT") {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,7 +133,7 @@ export default function SelectionToolbar(props: Props) {
|
||||
return () => {
|
||||
window.removeEventListener("mouseup", handleClickOutside);
|
||||
};
|
||||
}, [isActive, view]);
|
||||
}, [isActive, previousIsActive, readOnly, view]);
|
||||
|
||||
const handleOnCreateLink = async (title: string): Promise<void> => {
|
||||
const { onCreateLink } = props;
|
||||
@@ -143,7 +145,7 @@ export default function SelectionToolbar(props: Props) {
|
||||
const { dispatch, state } = view;
|
||||
const { from, to } = state.selection;
|
||||
if (from === to) {
|
||||
// selection cannot be collapsed
|
||||
// Do not display a selection toolbar for collapsed selections
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -184,7 +186,7 @@ export default function SelectionToolbar(props: Props) {
|
||||
);
|
||||
};
|
||||
|
||||
const { onCreateLink, isTemplate, rtl, ...rest } = props;
|
||||
const { onCreateLink, isTemplate, rtl, canComment, ...rest } = props;
|
||||
const { state } = view;
|
||||
const { selection }: { selection: any } = state;
|
||||
const isCodeSelection = isNodeActive(state.schema.nodes.code_block)(state);
|
||||
@@ -195,6 +197,11 @@ export default function SelectionToolbar(props: Props) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// no toolbar in this circumstance
|
||||
if (readOnly && !canComment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const colIndex = getColumnIndex(state);
|
||||
const rowIndex = getRowIndex(state);
|
||||
const isTableSelection = colIndex !== undefined && rowIndex !== undefined;
|
||||
@@ -213,6 +220,8 @@ export default function SelectionToolbar(props: Props) {
|
||||
items = getImageMenuItems(state, dictionary);
|
||||
} else if (isDividerSelection) {
|
||||
items = getDividerMenuItems(state, dictionary);
|
||||
} else if (readOnly) {
|
||||
items = getReadOnlyMenuItems(state, dictionary);
|
||||
} else {
|
||||
items = getFormattingMenuItems(state, isTemplate, isMobile, dictionary);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ type Props = { active?: boolean; disabled?: boolean };
|
||||
export default styled.button.attrs((props) => ({
|
||||
type: props.type || "button",
|
||||
}))<Props>`
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex: 0;
|
||||
width: 24px;
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
cursor: var(--pointer);
|
||||
border: none;
|
||||
|
||||
@@ -45,8 +45,12 @@ function ToolbarMenu(props: Props) {
|
||||
const isActive = item.active ? item.active(state) : false;
|
||||
|
||||
return (
|
||||
<Tooltip tooltip={item.tooltip} key={index}>
|
||||
<Tooltip
|
||||
tooltip={item.label === item.tooltip ? undefined : item.tooltip}
|
||||
key={index}
|
||||
>
|
||||
<ToolbarButton onClick={handleClick(item)} active={isActive}>
|
||||
{item.label && <Label>{item.label}</Label>}
|
||||
{item.icon}
|
||||
</ToolbarButton>
|
||||
</Tooltip>
|
||||
@@ -56,4 +60,9 @@ function ToolbarMenu(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
const Label = styled.span`
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
`;
|
||||
|
||||
export default ToolbarMenu;
|
||||
|
||||
Reference in New Issue
Block a user