mirror of
https://github.com/docmost/docmost.git
synced 2026-08-28 17:27:06 +08:00
feat: lightbox media display (#2420)
* lightbox media display init * revert uninteded changes * load page media more accurately * restrict lock file changes to installed packages * revert changes in lock file * update lockfile * - support diagrams - support readonly mode - use softer backdrop - other enhancments --------- Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
This commit is contained in:
@@ -23,11 +23,21 @@ import {
|
||||
} from "@/features/comment/atoms/comment-atom";
|
||||
import { useAtom, useAtomValue } from "jotai";
|
||||
import { v7 as uuid7 } from "uuid";
|
||||
import { isCellSelection, isEditorReady, isTextSelected } from "@docmost/editor-ext";
|
||||
import {
|
||||
isCellSelection,
|
||||
isEditorReady,
|
||||
isTextSelected,
|
||||
} from "@docmost/editor-ext";
|
||||
import { LinkSelector } from "@/features/editor/components/bubble-menu/link-selector.tsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { showAiMenuAtom, showLinkMenuAtom } from "@/features/editor/atoms/editor-atoms";
|
||||
import { userAtom, workspaceAtom } from "@/features/user/atoms/current-user-atom";
|
||||
import {
|
||||
showAiMenuAtom,
|
||||
showLinkMenuAtom,
|
||||
} from "@/features/editor/atoms/editor-atoms";
|
||||
import {
|
||||
userAtom,
|
||||
workspaceAtom,
|
||||
} from "@/features/user/atoms/current-user-atom";
|
||||
|
||||
export interface BubbleMenuItem {
|
||||
name: string;
|
||||
@@ -217,7 +227,12 @@ export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props) => {
|
||||
|
||||
<ActionIcon.Group>
|
||||
{items.map((item, index) => (
|
||||
<Tooltip key={index} label={t(item.name)} withArrow>
|
||||
<Tooltip
|
||||
key={index}
|
||||
label={t(item.name)}
|
||||
withArrow
|
||||
withinPortal={false}
|
||||
>
|
||||
<ActionIcon
|
||||
key={index}
|
||||
variant="default"
|
||||
@@ -226,7 +241,9 @@ export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props) => {
|
||||
aria-label={t(item.name)}
|
||||
className={clsx({ [classes.active]: item.isActive() })}
|
||||
style={{ border: "none" }}
|
||||
onClick={() => isEditorReady(props.editor) && item.command()}
|
||||
onClick={() =>
|
||||
isEditorReady(props.editor) && item.command()
|
||||
}
|
||||
>
|
||||
<item.icon style={{ width: rem(16) }} stroke={2} />
|
||||
</ActionIcon>
|
||||
@@ -256,7 +273,9 @@ export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props) => {
|
||||
radius="6px"
|
||||
aria-label={t(commentItem.name)}
|
||||
style={{ border: "none" }}
|
||||
onClick={() => isEditorReady(props.editor) && commentItem.command()}
|
||||
onClick={() =>
|
||||
isEditorReady(props.editor) && commentItem.command()
|
||||
}
|
||||
>
|
||||
<IconMessage size={16} stroke={2} />
|
||||
</ActionIcon>
|
||||
|
||||
@@ -129,8 +129,7 @@ function handleColorKeyNav(
|
||||
grid: "text" | "highlight",
|
||||
) {
|
||||
const cols = COLOR_GRID_COLS;
|
||||
const total =
|
||||
grid === "text" ? TEXT_COLORS.length : HIGHLIGHT_COLORS.length;
|
||||
const total = grid === "text" ? TEXT_COLORS.length : HIGHLIGHT_COLORS.length;
|
||||
const col = index % cols;
|
||||
|
||||
if (e.key === "ArrowRight") {
|
||||
@@ -163,8 +162,7 @@ function handleColorKeyNav(
|
||||
if (prev >= 0) {
|
||||
focusSwatch(grid, prev);
|
||||
} else if (grid === "highlight") {
|
||||
const lastRowStart =
|
||||
Math.floor((TEXT_COLORS.length - 1) / cols) * cols;
|
||||
const lastRowStart = Math.floor((TEXT_COLORS.length - 1) / cols) * cols;
|
||||
focusSwatch("text", Math.min(lastRowStart + col, TEXT_COLORS.length - 1));
|
||||
}
|
||||
return;
|
||||
@@ -222,7 +220,7 @@ export const ColorSelector: FC<ColorSelectorProps> = ({
|
||||
withArrow
|
||||
>
|
||||
<Popover.Target>
|
||||
<Tooltip label={t("Text color")} withArrow>
|
||||
<Tooltip label={t("Text color")} withArrow withinPortal={false}>
|
||||
<Button
|
||||
variant="default"
|
||||
radius="0"
|
||||
@@ -247,26 +245,26 @@ export const ColorSelector: FC<ColorSelectorProps> = ({
|
||||
|
||||
<Popover.Dropdown onMouseDown={(e) => e.preventDefault()}>
|
||||
<Stack gap="md" p="2px">
|
||||
<Box>
|
||||
<Text size="sm" fw={600} mb="xs">
|
||||
{t("Text color")}
|
||||
</Text>
|
||||
<SimpleGrid cols={5} spacing="xs">
|
||||
{TEXT_COLORS.map(({ name, color }, index) => {
|
||||
const applyTextColor = () => {
|
||||
if (!isEditorReady(editor)) return;
|
||||
if (name === "Default") {
|
||||
editor.commands.unsetColor();
|
||||
} else {
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.setColor(color || "")
|
||||
.run();
|
||||
}
|
||||
setIsOpen(false);
|
||||
};
|
||||
return (
|
||||
<Box>
|
||||
<Text size="sm" fw={600} mb="xs">
|
||||
{t("Text color")}
|
||||
</Text>
|
||||
<SimpleGrid cols={5} spacing="xs">
|
||||
{TEXT_COLORS.map(({ name, color }, index) => {
|
||||
const applyTextColor = () => {
|
||||
if (!isEditorReady(editor)) return;
|
||||
if (name === "Default") {
|
||||
editor.commands.unsetColor();
|
||||
} else {
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.setColor(color || "")
|
||||
.run();
|
||||
}
|
||||
setIsOpen(false);
|
||||
};
|
||||
return (
|
||||
<Tooltip key={index} label={t(name)} withArrow>
|
||||
<Box
|
||||
role="button"
|
||||
@@ -306,34 +304,34 @@ export const ColorSelector: FC<ColorSelectorProps> = ({
|
||||
A
|
||||
</Box>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text size="sm" fw={600} mb="xs">
|
||||
{t("Highlight color")}
|
||||
</Text>
|
||||
<SimpleGrid cols={5} spacing="xs">
|
||||
{HIGHLIGHT_COLORS.map(({ name, color }, index) => {
|
||||
const applyHighlight = () => {
|
||||
if (!isEditorReady(editor)) return;
|
||||
if (name === "Default") {
|
||||
editor.commands.unsetHighlight();
|
||||
} else {
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.toggleMark("highlight", {
|
||||
color: color || "",
|
||||
colorName: name.toLowerCase() || "",
|
||||
})
|
||||
.run();
|
||||
}
|
||||
setIsOpen(false);
|
||||
};
|
||||
return (
|
||||
<Box>
|
||||
<Text size="sm" fw={600} mb="xs">
|
||||
{t("Highlight color")}
|
||||
</Text>
|
||||
<SimpleGrid cols={5} spacing="xs">
|
||||
{HIGHLIGHT_COLORS.map(({ name, color }, index) => {
|
||||
const applyHighlight = () => {
|
||||
if (!isEditorReady(editor)) return;
|
||||
if (name === "Default") {
|
||||
editor.commands.unsetHighlight();
|
||||
} else {
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.toggleMark("highlight", {
|
||||
color: color || "",
|
||||
colorName: name.toLowerCase() || "",
|
||||
})
|
||||
.run();
|
||||
}
|
||||
setIsOpen(false);
|
||||
};
|
||||
return (
|
||||
<Tooltip key={index} label={t(name)} withArrow>
|
||||
<Box
|
||||
role="button"
|
||||
@@ -378,37 +376,36 @@ export const ColorSelector: FC<ColorSelectorProps> = ({
|
||||
)}
|
||||
</Box>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
|
||||
<Button
|
||||
variant="default"
|
||||
fullWidth
|
||||
data-color-grid="remove"
|
||||
className={classes.removeColor}
|
||||
onClick={() => {
|
||||
if (isEditorReady(editor)) {
|
||||
editor.commands.unsetColor();
|
||||
editor.commands.unsetHighlight();
|
||||
}
|
||||
setIsOpen(false);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "ArrowUp") {
|
||||
e.preventDefault();
|
||||
const lastRowStart =
|
||||
Math.floor(
|
||||
(HIGHLIGHT_COLORS.length - 1) / COLOR_GRID_COLS,
|
||||
) * COLOR_GRID_COLS;
|
||||
focusSwatch("highlight", lastRowStart);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("Remove color")}
|
||||
</Button>
|
||||
</Stack>
|
||||
<Button
|
||||
variant="default"
|
||||
fullWidth
|
||||
data-color-grid="remove"
|
||||
className={classes.removeColor}
|
||||
onClick={() => {
|
||||
if (isEditorReady(editor)) {
|
||||
editor.commands.unsetColor();
|
||||
editor.commands.unsetHighlight();
|
||||
}
|
||||
setIsOpen(false);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "ArrowUp") {
|
||||
e.preventDefault();
|
||||
const lastRowStart =
|
||||
Math.floor((HIGHLIGHT_COLORS.length - 1) / COLOR_GRID_COLS) *
|
||||
COLOR_GRID_COLS;
|
||||
focusSwatch("highlight", lastRowStart);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("Remove color")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
);
|
||||
|
||||
@@ -10,7 +10,7 @@ export const LinkSelector: FC = () => {
|
||||
const setShowLinkMenu = useSetAtom(showLinkMenuAtom);
|
||||
|
||||
return (
|
||||
<Tooltip label={t("Add link")} withArrow>
|
||||
<Tooltip label={t("Add link")} withArrow withinPortal={false}>
|
||||
<ActionIcon
|
||||
variant="default"
|
||||
size="lg"
|
||||
|
||||
@@ -91,7 +91,12 @@ export const TextAlignmentSelector: FC<TextAlignmentProps> = ({
|
||||
onChange={setIsOpen}
|
||||
>
|
||||
<Menu.Target>
|
||||
<Tooltip label={t("Text align")} withArrow disabled={isOpen}>
|
||||
<Tooltip
|
||||
label={t("Text align")}
|
||||
withArrow
|
||||
disabled={isOpen}
|
||||
withinPortal={false}
|
||||
>
|
||||
<Button
|
||||
variant="default"
|
||||
style={{ border: "none", height: "34px" }}
|
||||
|
||||
Reference in New Issue
Block a user