+
-
-
+
-
)
@@ -147,11 +95,10 @@ export const LinkDialog: React.FC = () => {
'linkDialogState',
'linkAutocompleteSuggestions'
)
- const updateLinkUrl = linkDialogPluginHooks.usePublisher('updateLinkUrl')
+ const updateLink = linkDialogPluginHooks.usePublisher('updateLink')
const cancelLinkEdit = linkDialogPluginHooks.usePublisher('cancelLinkEdit')
const switchFromPreviewToLinkEdit = linkDialogPluginHooks.usePublisher('switchFromPreviewToLinkEdit')
const removeLink = linkDialogPluginHooks.usePublisher('removeLink')
- const applyLinkChanges = linkDialogPluginHooks.usePublisher('applyLinkChanges')
React.useEffect(() => {
const update = () => {
@@ -173,14 +120,6 @@ export const LinkDialog: React.FC = () => {
const theRect = linkDialogState?.rectangle
- const onSubmitEH = React.useCallback(
- (payload: [string, string]) => {
- updateLinkUrl(payload)
- applyLinkChanges(true)
- },
- [applyLinkChanges, updateLinkUrl]
- )
-
const urlIsExternal = linkDialogState.type === 'preview' && linkDialogState.url.startsWith('http')
return (
@@ -205,9 +144,9 @@ export const LinkDialog: React.FC = () => {
>
{linkDialogState.type === 'edit' && (
diff --git a/src/plugins/link-dialog/index.ts b/src/plugins/link-dialog/index.ts
index 71a0b352..5674562b 100644
--- a/src/plugins/link-dialog/index.ts
+++ b/src/plugins/link-dialog/index.ts
@@ -64,7 +64,7 @@ const linkDialogSystem = system(
const linkDialogState = r.node
({ type: 'inactive' }, true)
// actions
- const updateLinkUrl = r.node<[string, string]>()
+ const updateLink = r.node<{ url: string; title: string }>()
const cancelLinkEdit = r.node()
const applyLinkChanges = r.node()
const switchFromPreviewToLinkEdit = r.node()
@@ -169,59 +169,36 @@ const linkDialogSystem = system(
linkDialogState
)
- r.sub(r.pipe(applyLinkChanges, r.o.withLatestFrom(linkDialogState, activeEditor)), ([, state, editor]) => {
- if (state.type === 'edit') {
- const url = state.url.trim()
- const title = state.title.trim()
+ r.sub(r.pipe(updateLink, r.o.withLatestFrom(activeEditor, linkDialogState)), ([payload, editor, state]) => {
+ const url = payload.url.trim()
+ const title = payload.title.trim()
- if (url.trim() !== '') {
- editor?.dispatchCommand(TOGGLE_LINK_COMMAND, { url, title })
- // the dispatch command implementation fails to set the link for a fresh link creation.
- // Work around with the code below.
- setTimeout(() => {
- editor?.update(() => {
- const node = getLinkNodeInSelection($getSelection() as RangeSelection)
- node?.setTitle(title)
- })
- })
- r.pub(linkDialogState, {
- type: 'preview',
- linkNodeKey: state.linkNodeKey,
- rectangle: state.rectangle,
- url
- })
- } else {
- if (state.initialUrl !== '') {
- editor?.dispatchCommand(TOGGLE_LINK_COMMAND, null)
- }
- r.pub(linkDialogState, {
- type: 'inactive'
+ if (url.trim() !== '') {
+ editor?.dispatchCommand(TOGGLE_LINK_COMMAND, { url, title })
+ // the dispatch command implementation fails to set the link for a fresh link creation.
+ // Work around with the code below.
+ setTimeout(() => {
+ editor?.update(() => {
+ const node = getLinkNodeInSelection($getSelection() as RangeSelection)
+ node?.setTitle(title)
})
- }
+ })
+ r.pub(linkDialogState, {
+ type: 'preview',
+ linkNodeKey: state.linkNodeKey,
+ rectangle: state.rectangle,
+ url
+ } as PreviewLinkDialog)
} else {
- throw new Error('Cannot apply link edit when not in edit mode')
+ if (state.type === 'edit' && state.initialUrl !== '') {
+ editor?.dispatchCommand(TOGGLE_LINK_COMMAND, null)
+ }
+ r.pub(linkDialogState, {
+ type: 'inactive'
+ })
}
})
- r.link(
- r.pipe(
- updateLinkUrl,
- r.o.withLatestFrom(linkDialogState),
- r.o.map(([[url, title], state]) => {
- if (state.type === 'edit') {
- return {
- ...state,
- url,
- title
- }
- } else {
- throw new Error('Cannot update link url when not in edit mode')
- }
- })
- ),
- linkDialogState
- )
-
r.link(
r.pipe(
cancelLinkEdit,
@@ -283,7 +260,7 @@ const linkDialogSystem = system(
dialogState,
onWindowChange,
linkDialogState,
- updateLinkUrl,
+ updateLink,
switchFromPreviewToLinkEdit,
cancelLinkEdit,
removeLink,
diff --git a/src/plugins/toolbar/components/InsertImage.tsx b/src/plugins/toolbar/components/InsertImage.tsx
index 9ae0d626..ee7314cc 100644
--- a/src/plugins/toolbar/components/InsertImage.tsx
+++ b/src/plugins/toolbar/components/InsertImage.tsx
@@ -1,178 +1,24 @@
-/* eslint-disable @typescript-eslint/no-unsafe-call */
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
-/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import React from 'react'
import { imagePluginHooks } from '../../image'
import * as RadixToolbar from '@radix-ui/react-toolbar'
-import * as Dialog from '@radix-ui/react-dialog'
import AddPhotoIcon from '../../../icons/add_photo.svg'
import styles from '../../../styles/ui.module.css'
import { corePluginHooks } from '../../core/index'
import { TooltipWrap } from '../primitives/TooltipWrap'
-import { useCombobox } from 'downshift'
-import classNames from 'classnames'
-import DropDownIcon from '../../../icons/arrow_drop_down.svg'
-import { useForm, Controller, Control } from 'react-hook-form'
-interface ImageFormFields {
- src?: string
- title: string
- altText?: string
- file?: File
-}
-
-const MAX_SUGGESTIONS = 20
/**
* A toolbar button that allows the user to insert an image from an URL.
* For the button to work, you need to have the `imagePlugin` plugin enabled.
*/
export const InsertImage = React.forwardRef>((_, forwardedRef) => {
- const [imageAutocompleteSuggestions] = imagePluginHooks.useEmitterValues('imageAutocompleteSuggestions')
- const insertImage = imagePluginHooks.usePublisher('insertImage')
- const [editorRootElementRef, readOnly] = corePluginHooks.useEmitterValues('editorRootElementRef', 'readOnly')
- const [open, setOpen] = React.useState(false)
- const { register, handleSubmit, control } = useForm()
+ const openNewImageDialog = imagePluginHooks.usePublisher('openNewImageDialog')
+ const [readOnly] = corePluginHooks.useEmitterValues('readOnly')
return (
-
-
-
-
-
-
-
-
-
-
- e.preventDefault()}>
-
-
-
-
+ openNewImageDialog(true)}>
+
+
+
+
)
})
-
-const DownshiftAutoComplete: React.FC<{ suggestions: string[]; control: Control; placeholder: string; inputName: string }> = ({
- suggestions,
- control,
- inputName,
- placeholder
-}) => {
- const [items, setItems] = React.useState(suggestions.slice(0, MAX_SUGGESTIONS))
-
- const enableAutoComplete = suggestions.length > 0
-
- const { isOpen, getToggleButtonProps, getMenuProps, getInputProps, highlightedIndex, getItemProps, selectedItem } = useCombobox({
- initialInputValue: '',
- onInputValueChange({ inputValue }) {
- inputValue = inputValue?.toLowerCase() || ''
- const matchingItems = []
- for (const suggestion of suggestions) {
- if (suggestion.toLowerCase().includes(inputValue)) {
- matchingItems.push(suggestion)
- if (matchingItems.length >= MAX_SUGGESTIONS) {
- break
- }
- }
- }
- setItems(matchingItems)
- },
- items,
- itemToString(item) {
- return item ?? ''
- }
- })
-
- const dropdownIsVisible = isOpen && items.length > 0
- return (
-
-
- {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- const downshiftSrcProps = getInputProps({
- onSelect: field.onChange,
- onBlur: field.onBlur,
- ref: field.ref
- })
- return (
-
- )
- }}
- />
- {enableAutoComplete && (
-
- )}
-
-
-
-
- {items.map((item, index: number) => (
- -
- {item}
-
- ))}
-
-
-
- )
-}
diff --git a/src/plugins/toolbar/primitives/DialogButton.tsx b/src/plugins/toolbar/primitives/DialogButton.tsx
index c3a2f91d..d78adf66 100644
--- a/src/plugins/toolbar/primitives/DialogButton.tsx
+++ b/src/plugins/toolbar/primitives/DialogButton.tsx
@@ -147,7 +147,7 @@ const DialogForm: React.FC<{
const onSubmitEH = (e: React.FormEvent) => {
e.preventDefault()
- e.stopPropagation()
+ e.nativeEvent.stopImmediatePropagation()
onSubmitCallback((inputProps as { value: string }).value)
}
diff --git a/src/styles/ui.module.css b/src/styles/ui.module.css
index ee49e1a4..5adfab5d 100644
--- a/src/styles/ui.module.css
+++ b/src/styles/ui.module.css
@@ -476,6 +476,7 @@
flex-direction: column;
align-items: stretch;
gap: var(--spacing-2);
+ padding: 0;
}
.linkDialogInputContainer {
@@ -826,6 +827,18 @@
cursor: -webkit-grab;
}
+.editImageButton {
+ position: absolute;
+ right: var(--spacing-2);
+ top: var(--spacing-2);
+ background: var(--baseBase);
+ border-radius: var(--radius-full);
+
+ & svg {
+ display: block;
+ }
+}
+
.inlineEditor {
display: inline-flex;
border-radius: var(--radius-medium);
@@ -1066,6 +1079,7 @@
all: unset;
border-radius: var(--radius-base);
border:1px solid var(--baseBorder);
+ background-color: var(--baseBase);
padding: var(--spacing-2) var(--spacing-3);
}