From f161f677ac916eb87b97a9e5669a165d124d49e5 Mon Sep 17 00:00:00 2001 From: Brandon <29527680+ChronicLynx@users.noreply.github.com> Date: Mon, 6 Mar 2023 02:57:55 -0700 Subject: [PATCH] Improved link editor UX (#4026) --- .../lexical-playground/src/appSettings.ts | 2 + .../src/images/icons/success-alt.svg | 1 + packages/lexical-playground/src/index.css | 55 +++++++++++- .../FloatingLinkEditorPlugin/index.css | 1 + .../FloatingLinkEditorPlugin/index.tsx | 83 ++++++++++++++----- 5 files changed, 115 insertions(+), 27 deletions(-) create mode 100644 packages/lexical-playground/src/images/icons/success-alt.svg diff --git a/packages/lexical-playground/src/appSettings.ts b/packages/lexical-playground/src/appSettings.ts index 44356bc385f..355da980c13 100644 --- a/packages/lexical-playground/src/appSettings.ts +++ b/packages/lexical-playground/src/appSettings.ts @@ -18,6 +18,7 @@ export type SettingName = | 'showTreeView' | 'showNestedEditorTreeView' | 'emptyEditor' + | 'enableLinkPreviews' | 'showTableOfContents'; export type Settings = Record; @@ -30,6 +31,7 @@ export const isDevPlayground: boolean = export const DEFAULT_SETTINGS: Settings = { disableBeforeInput: false, emptyEditor: isDevPlayground, + enableLinkPreviews: false, isAutocomplete: false, isCharLimit: false, isCharLimitUtf8: false, diff --git a/packages/lexical-playground/src/images/icons/success-alt.svg b/packages/lexical-playground/src/images/icons/success-alt.svg new file mode 100644 index 00000000000..c9d4ad9c230 --- /dev/null +++ b/packages/lexical-playground/src/images/icons/success-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/lexical-playground/src/index.css b/packages/lexical-playground/src/index.css index faa8e4405e4..1408f3cdbd6 100644 --- a/packages/lexical-playground/src/index.css +++ b/packages/lexical-playground/src/index.css @@ -559,9 +559,9 @@ i.prettier-error { .link-editor .link-input { display: block; - width: calc(100% - 24px); + width: calc(100% - 75px); box-sizing: border-box; - margin: 8px 12px; + margin: 12px 12px; padding: 8px 12px; border-radius: 15px; background-color: #eee; @@ -573,6 +573,20 @@ i.prettier-error { font-family: inherit; } +.link-editor .link-view { + display: block; + width: calc(100% - 24px); + margin: 8px 12px; + padding: 8px 12px; + border-radius: 15px; + font-size: 15px; + color: rgb(5, 5, 5); + border: 0; + outline: 0; + position: relative; + font-family: inherit; +} + .link-editor div.link-edit { background-image: url(images/icons/pencil-fill.svg); background-size: 16px; @@ -587,10 +601,39 @@ i.prettier-error { cursor: pointer; } +.link-editor div.link-cancel { + background-image: url(images/icons/close.svg); + background-size: 16px; + background-position: center; + background-repeat: no-repeat; + width: 35px; + vertical-align: -0.25em; + margin-right: 28px; + position: absolute; + right: 0; + top: 0; + bottom: 0; + cursor: pointer; +} + +.link-editor div.link-confirm { + background-image: url(images/icons/success-alt.svg); + background-size: 16px; + background-position: center; + background-repeat: no-repeat; + width: 35px; + vertical-align: -0.25em; + margin-right: 2px; + position: absolute; + right: 0; + top: 0; + bottom: 0; + cursor: pointer; +} + .link-editor .link-input a { color: rgb(33, 111, 219); - text-decoration: none; - display: block; + text-decoration: underline; white-space: nowrap; overflow: hidden; margin-right: 30px; @@ -614,6 +657,10 @@ i.prettier-error { border-radius: 4px; } +.ContentEditable__root .PlaygroundEditorTheme__link { + pointer-events: none; +} + .mention:focus { box-shadow: rgb(180 213 255) 0px 0px 0px 2px; outline: none; diff --git a/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.css b/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.css index 55732191f26..0ac8b509357 100644 --- a/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.css +++ b/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.css @@ -1,4 +1,5 @@ .link-editor { + display: flex; position: absolute; top: 0; left: 0; diff --git a/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.tsx b/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.tsx index 5899bc2d6a0..d56ea4776d9 100644 --- a/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.tsx +++ b/packages/lexical-playground/src/plugins/FloatingLinkEditorPlugin/index.tsx @@ -27,6 +27,7 @@ import {Dispatch, useCallback, useEffect, useRef, useState} from 'react'; import * as React from 'react'; import {createPortal} from 'react-dom'; +import {useSettings} from '../../context/SettingsContext'; import LinkPreview from '../../ui/LinkPreview'; import {getSelectedNode} from '../../utils/getSelectedNode'; import {setFloatingElemPosition} from '../../utils/setFloatingElemPosition'; @@ -43,9 +44,13 @@ function FloatingLinkEditor({ setIsLink: Dispatch; anchorElem: HTMLElement; }): JSX.Element { + const { + settings: {enableLinkPreviews}, + } = useSettings(); const editorRef = useRef(null); const inputRef = useRef(null); const [linkUrl, setLinkUrl] = useState(''); + const [editedLinkUrl, setEditedLinkUrl] = useState(''); const [isEditMode, setEditMode] = useState(false); const [lastSelection, setLastSelection] = useState< RangeSelection | GridSelection | NodeSelection | null @@ -196,34 +201,65 @@ function FloatingLinkEditor({ } }, [isEditMode]); + const monitorInputInteraction = ( + event: React.KeyboardEvent, + ) => { + if (event.key === 'Enter') { + event.preventDefault(); + handleLinkSubmission(); + } else if (event.key === 'Escape') { + event.preventDefault(); + setEditMode(false); + } + }; + + const handleLinkSubmission = () => { + if (lastSelection !== null) { + if (linkUrl !== '') { + editor.dispatchCommand(TOGGLE_LINK_COMMAND, sanitizeUrl(editedLinkUrl)); + } + setEditMode(false); + } + }; + return (
{!isLink ? null : isEditMode ? ( - { - setLinkUrl(event.target.value); - }} - onKeyDown={(event) => { - if (event.key === 'Enter' || event.key === 'Escape') { - event.preventDefault(); - if (lastSelection !== null) { - if (linkUrl !== '') { - editor.dispatchCommand( - TOGGLE_LINK_COMMAND, - sanitizeUrl(linkUrl), - ); - } + <> + { + setEditedLinkUrl(event.target.value); + }} + onKeyDown={(event) => { + monitorInputInteraction(event); + }} + /> +
+
event.preventDefault()} + onClick={() => { setEditMode(false); - } - } - }} - /> + }} + /> + +
event.preventDefault()} + onClick={handleLinkSubmission} + /> +
+ ) : ( <> -
+
{linkUrl} @@ -233,11 +269,12 @@ function FloatingLinkEditor({ tabIndex={0} onMouseDown={(event) => event.preventDefault()} onClick={() => { + setEditedLinkUrl(linkUrl); setEditMode(true); }} />
- + {enableLinkPreviews ? : ''} )}