Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfeng33 committed Nov 15, 2024
1 parent 72ae7a7 commit a0d0880
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 235 deletions.
102 changes: 56 additions & 46 deletions apps/www/src/registry/default/plate-ui/media-dropdown-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import React from 'react';
import React, { useState } from 'react';

import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';

Expand Down Expand Up @@ -31,6 +31,7 @@ import {
DropdownMenuTrigger,
useOpenState,
} from './dropdown-menu';
import { MediaEmbedPopover } from './media-embed-popover';
import {
ToolbarSplitButton,
ToolbarSplitButtonPrimary,
Expand Down Expand Up @@ -72,9 +73,10 @@ export function MediaDropdownMenu({
nodeType,
...props
}: DropdownMenuProps & { nodeType: string }) {
const currentConfig = MEDIA_CONFIG[nodeType];
const { editor } = useEditorPlugin(MediaEmbedPlugin);
const [isPopoverOpen, setIsPopoverOpen] = useState(false);

const { editor, setOptions } = useEditorPlugin(MediaEmbedPlugin);
const currentConfig = MEDIA_CONFIG[nodeType];
const { openFilePicker } = useFilePicker({
accept: currentConfig.accept,
multiple: true,
Expand All @@ -86,50 +88,58 @@ export function MediaDropdownMenu({
const openState = useOpenState();

return (
<DropdownMenu {...openState} modal={false} {...props}>
<ToolbarSplitButton
pressed={openState.open}
tooltip={currentConfig.tooltip}
>
<ToolbarSplitButtonPrimary onClick={() => openFilePicker()}>
{currentConfig.icon}
</ToolbarSplitButtonPrimary>
<>
<DropdownMenu {...openState} modal={false} {...props}>
<ToolbarSplitButton
pressed={openState.open}
tooltip={currentConfig.tooltip}
>
<ToolbarSplitButtonPrimary onClick={() => openFilePicker()}>
{currentConfig.icon}
</ToolbarSplitButtonPrimary>

<DropdownMenuTrigger asChild>
<ToolbarSplitButtonSecondary />
</DropdownMenuTrigger>
</ToolbarSplitButton>

<DropdownMenuTrigger asChild>
<ToolbarSplitButtonSecondary />
</DropdownMenuTrigger>
</ToolbarSplitButton>
<DropdownMenuContent
className={cn('min-w-0 data-[state=closed]:hidden')}
align="start"
>
<DropdownMenuRadioGroup>
<DropdownMenuRadioItem
value="upload"
onSelect={() => openFilePicker()}
hideIcon
>
<div className="flex items-center gap-2">
{currentConfig.icon}
<span className="text-sm">Upload from computer</span>
</div>
</DropdownMenuRadioItem>
<DropdownMenuRadioItem
value="url"
onSelect={() => {
focusEditor(editor);
setIsPopoverOpen(true);
}}
hideIcon
>
<div className="flex items-center gap-2">
<LinkIcon />
<span className="text-sm">Insert via URL</span>
</div>
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>

<DropdownMenuContent
className={cn('min-w-0 data-[state=closed]:hidden')}
align="start"
>
<DropdownMenuRadioGroup>
<DropdownMenuRadioItem
value="upload"
onSelect={() => openFilePicker()}
hideIcon
>
<div className="flex items-center gap-2">
{currentConfig.icon}
<span className="text-sm">Upload from computer</span>
</div>
</DropdownMenuRadioItem>
<DropdownMenuRadioItem
value="url"
onSelect={() => {
focusEditor(editor);
setOptions({ isOpen: true, mediaType: nodeType });
}}
hideIcon
>
<div className="flex items-center gap-2">
<LinkIcon />
<span className="text-sm">Insert via URL</span>
</div>
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
<MediaEmbedPopover
onOpenChange={setIsPopoverOpen}
isOpen={isPopoverOpen}
mediaType={nodeType}
/>
</>
);
}
69 changes: 36 additions & 33 deletions apps/www/src/registry/default/plate-ui/media-embed-popover.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
'use client';

import React, { useMemo } from 'react';
import React, { useCallback, useMemo, useState } from 'react';

import { useEditorPlugin, useEditorSelector } from '@udecode/plate-core/react';
import { focusEditor } from '@udecode/plate-common/react';
import { useEditorPlugin } from '@udecode/plate-core/react';
import { insertImage } from '@udecode/plate-media';
import {
AudioPlugin,
FilePlugin,
ImagePlugin,
MediaEmbedPlugin,
VideoPlugin,
useMediaEmbedPopover,
} from '@udecode/plate-media/react';
import { toDOMNode } from '@udecode/slate-react';
import { getAncestorNode } from '@udecode/slate-utils';
import { useLastBlockDOMNode } from '@udecode/plate-utils/react';
import { AudioLinesIcon, FileUpIcon, FilmIcon, ImageIcon } from 'lucide-react';

import { Button } from './button';
Expand Down Expand Up @@ -45,41 +45,36 @@ const MEDIA_CONFIG: Record<
},
};

export function MediaEmbedPopover() {
const { setOption, useOption } = useEditorPlugin(MediaEmbedPlugin);

const mediaType = useOption('mediaType');
const isOpen = useOption('isOpen');

const anchorElement = useEditorSelector(
(editor) => {
if (!isOpen) return null;

const enter = getAncestorNode(editor);

if (!enter) return null;

return toDOMNode(editor, enter[0]);
},
[isOpen]
);
export function MediaEmbedPopover({
isOpen,
mediaType,
onOpenChange,
}: {
isOpen: boolean;
mediaType: string;
onOpenChange: (open: boolean) => void;
}) {
const { editor } = useEditorPlugin(MediaEmbedPlugin);
const [url, setUrl] = useState('');

const anchorElement = useLastBlockDOMNode(editor, { enabled: isOpen });

const embedMedia = useCallback(() => {
insertImage(editor, url);
focusEditor(editor);
onOpenChange(false);
}, [editor, url, onOpenChange]);

const mediaConfig = useMemo(() => {
if (!mediaType) return null;

return MEDIA_CONFIG[mediaType];
}, [mediaType]);

const { acceptProps, cancelProps, inputProps } = useMediaEmbedPopover();

if (!anchorElement) return null;

return (
<Popover
open={isOpen}
onOpenChange={(open) => setOption('isOpen', open)}
modal={false}
>
<Popover open={isOpen} onOpenChange={onOpenChange} modal={false}>
<PopoverAnchor virtualRef={{ current: anchorElement }} />

<PopoverContent className="w-auto p-1" align="center" side="bottom">
Expand All @@ -90,17 +85,25 @@ export function MediaEmbedPopover() {
</div>
<Input
variant="ghost"
{...inputProps}
value={url}
onChange={(e) => setUrl(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') embedMedia();
}}
placeholder={mediaConfig?.placeholder}
h="sm"
/>
</div>
<Separator className="my-1" />
<div className="flex items-center justify-end gap-2 pt-2">
<Button size="sm" variant="secondary" {...cancelProps}>
<Button
size="sm"
variant="secondary"
onClick={() => onOpenChange(false)}
>
Cancel
</Button>
<Button size="sm" variant="default" {...acceptProps}>
<Button size="sm" variant="default" onClick={embedMedia}>
Accept
</Button>
</div>
Expand Down
14 changes: 3 additions & 11 deletions packages/media/src/lib/media-embed/BaseMediaEmbedPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import {
type PluginConfig,
createTSlatePlugin,
isUrl,
} from '@udecode/plate-common';
import { type PluginConfig, createTSlatePlugin } from '@udecode/plate-common';

import type { MediaPluginOptions, TMediaElement } from '../media/index';

import { parseIframeUrl } from './parseIframeUrl';

export interface TMediaEmbedElement extends TMediaElement {}

export type BaseMediaEmbedConfig = PluginConfig<
'media_embed',
MediaPluginOptions
>;
export type MediaEmbedConfig = PluginConfig<'media_embed', MediaPluginOptions>;

/**
* Enables support for embeddable media such as YouTube or Vimeo videos,
* Instagram posts and tweets or Google Maps.
*/
export const BaseMediaEmbedPlugin = createTSlatePlugin<BaseMediaEmbedConfig>({
export const BaseMediaEmbedPlugin = createTSlatePlugin<MediaEmbedConfig>({
key: 'media_embed',
node: { isElement: true, isVoid: true },
options: {
isUrl: isUrl,
transformUrl: parseIframeUrl,
},
}).extend(({ type }) => ({
Expand Down
41 changes: 0 additions & 41 deletions packages/media/src/react/media/MediaEmbedPlugin.tsx

This file was deleted.

7 changes: 0 additions & 7 deletions packages/media/src/react/media/Popover/index.ts

This file was deleted.

22 changes: 0 additions & 22 deletions packages/media/src/react/media/Popover/useMediaEmbedEnter.ts

This file was deleted.

26 changes: 0 additions & 26 deletions packages/media/src/react/media/Popover/useMediaEmbedEscape.ts

This file was deleted.

Loading

0 comments on commit a0d0880

Please sign in to comment.