Skip to content

Commit

Permalink
feat: Edit link from the preview
Browse files Browse the repository at this point in the history
  • Loading branch information
areknawo committed Jun 16, 2024
1 parent c700d85 commit e333517
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 39 deletions.
19 changes: 13 additions & 6 deletions apps/web/src/views/editor/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BubbleMenu, LinkPreviewMenu, FloatingMenu } from "./menus";
import { BubbleMenu, LinkPreviewMenu, FloatingMenu, BubbleMenuMode } from "./menus";
import {
BubbleMenuWrapper,
FloatingMenuWrapper,
Expand Down Expand Up @@ -88,7 +88,7 @@ const Editor: ParentComponent<EditorProps & { docName: string; editable?: boolea
const [bubbleMenuInstance, setBubbleMenuInstance] = createSignal<Instance | null>(null);
const [floatingMenuOpened, setFloatingMenuOpened] = createSignal(true);
const [blockMenuOpened, setBlockMenuOpened] = createSignal(false);
const [showBlockBubbleMenu, setShowBlockBubbleMenu] = createSignal(false);
const [forceBubbleMenu, setForceBubbleMenu] = createSignal<BubbleMenuMode | undefined>();
const [isNodeSelection, setIsNodeSelection] = createSignal(false);
const [activeElement, setActiveElement] = createRef<HTMLElement | null>(null);
const baseBlockMenuOptions = createMemo(() => {
Expand Down Expand Up @@ -298,7 +298,14 @@ const Editor: ParentComponent<EditorProps & { docName: string; editable?: boolea
>
<LinkPreviewWrapper editor={editor()}>
{(link, tippyInstance) => {
return <LinkPreviewMenu link={link} tippyInstance={tippyInstance} />;
return (
<LinkPreviewMenu
link={link}
editor={editor()}
tippyInstance={tippyInstance}
setBubbleMenu={setForceBubbleMenu}
/>
);
}}
</LinkPreviewWrapper>

Expand All @@ -320,12 +327,12 @@ const Editor: ParentComponent<EditorProps & { docName: string; editable?: boolea
}}
shouldShow={({ editor }) => {
if (!breakpoints.md() && shouldShowFloatingMenu(editor as SolidEditor)) {
setShowBlockBubbleMenu(true);
setForceBubbleMenu("block");

return true;
}

setShowBlockBubbleMenu(false);
setForceBubbleMenu(undefined);

if (isNodeSelection()) {
bubbleMenuInstance()?.setProps({
Expand All @@ -341,7 +348,7 @@ const Editor: ParentComponent<EditorProps & { docName: string; editable?: boolea
editor={editor()}
opened={bubbleMenuOpened()}
setBlockMenuOpened={setBlockMenuOpened}
mode={showBlockBubbleMenu() ? "block" : undefined}
mode={forceBubbleMenu()}
blur={() => {
editor().commands.blur();
setActiveElement(null);
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/views/editor/menus/bubble/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,4 @@ const BubbleMenu: Component<BubbleMenuProps> = (props) => {
};

export { BubbleMenu };
export type { BubbleMenuMode };
85 changes: 52 additions & 33 deletions apps/web/src/views/editor/menus/link-preview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { BubbleMenuMode } from "../bubble";
import { Accessor, Component, createMemo, createResource, Show } from "solid-js";
import { mdiWeb, mdiFileDocumentOutline } from "@mdi/js";
import { mdiWeb, mdiFileDocumentOutline, mdiPencil } from "@mdi/js";
import clsx from "clsx";
import { Instance } from "tippy.js";
import { SolidEditor } from "@vrite/tiptap-solid";
import { App, useAuthenticatedUserData, useClient, useContentData } from "#context";
import { Card, Icon, IconButton, Loader } from "#components/primitives";
import { Card, Icon, IconButton, Loader, Tooltip } from "#components/primitives";

interface LinkPreviewMenuProps {
editor: SolidEditor;
link: Accessor<string>;
tippyInstance: Accessor<Instance | undefined>;
setBubbleMenu(mode: BubbleMenuMode | undefined): void;
}

const LinkPreviewMenu: Component<LinkPreviewMenuProps> = (props) => {
Expand Down Expand Up @@ -84,40 +88,55 @@ const LinkPreviewMenu: Component<LinkPreviewMenuProps> = (props) => {
<Show when={previewData()?.description}>
<p class="mt-0 mb-2 text-sm px-2">{previewData()?.description}</p>
</Show>
<Show
when={previewData()?.title}
fallback={
<div class="flex gap-1">
<Show
when={previewData()?.title}
fallback={
<IconButton
path={previewData()?.type === "internal" ? mdiFileDocumentOutline : mdiWeb}
badge
class="m-0"
text="soft"
label="Visit website"
/>
}
>
<div class="flex items-start justify-start text-base">
<Show
when={icon()}
fallback={
<Icon
path={previewData()?.type === "internal" ? mdiFileDocumentOutline : mdiWeb}
class="h-6 w-6"
/>
}
>
<img src={icon()} class="w-6 h-6 mr-1" />
</Show>
<div class="flex flex-col flex-1 justify-start items-start pl-1 text-left">
<span class="flex-1 text-start font-semibold clamp-1 break-all">
{previewData()?.title}
</span>
<span class="text-xs text-gray-500 dark:text-gray-400 font-mono clamp-1 break-all">
{previewData()?.url}
</span>
</div>
</div>
</Show>
<Tooltip text="Edit link" class="mt-1" fixed>
<IconButton
path={previewData()?.type === "internal" ? mdiFileDocumentOutline : mdiWeb}
badge
class="m-0"
path={mdiPencil}
text="soft"
label="Visit website"
variant="text"
class="m-0"
onClick={(event) => {
props.editor.chain().extendMarkRange("link").focus().run();
props.setBubbleMenu("link");
event.preventDefault();
}}
/>
}
>
<div class="flex items-start justify-start text-base">
<Show
when={icon()}
fallback={
<Icon
path={previewData()?.type === "internal" ? mdiFileDocumentOutline : mdiWeb}
class="h-6 w-6"
/>
}
>
<img src={icon()} class="w-6 h-6 mr-1" />
</Show>
<div class="flex flex-col flex-1 justify-start items-start pl-1 text-left">
<span class="flex-1 text-start font-semibold clamp-1 break-all">
{previewData()?.title}
</span>
<span class="text-xs text-gray-500 dark:text-gray-400 font-mono clamp-1 break-all">
{previewData()?.url}
</span>
</div>
</div>
</Show>
</Tooltip>
</div>
</Show>
</Card>
</a>
Expand Down

0 comments on commit e333517

Please sign in to comment.