Skip to content

Commit

Permalink
Update link editor (#1195)
Browse files Browse the repository at this point in the history
* Update link editor

* fixes

* cleanup

* restore offsets

* replace a element with Link

* use a element

* make link an edit button instead of clickable

* Set editMode on first open

* Focus improvements

* a11y and translation strings

* label for dialog

* aria-label for text area

* Add aria-controls to toolbar/editor
  • Loading branch information
dsamojlenko committed Nov 4, 2022
1 parent 4c9b156 commit abb7be0
Show file tree
Hide file tree
Showing 11 changed files with 492 additions and 296 deletions.
16 changes: 16 additions & 0 deletions components/form-builder/icons/EditIcon.tsx
@@ -0,0 +1,16 @@
import React from "react";
export const EditIcon = ({ className, title }: { className?: string; title?: string }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height="48"
width="48"
className={className}
viewBox="0 0 48 48"
focusable="false"
aria-hidden={title ? false : true}
role={title ? "img" : "presentation"}
>
{title && <title>{title}</title>}
<path d="M9 39h2.2l22.15-22.15-2.2-2.2L9 36.8Zm30.7-24.3-6.4-6.4 2.1-2.1q.85-.85 2.1-.85t2.1.85l2.2 2.2q.85.85.85 2.1t-.85 2.1Zm-2.1 2.1L12.4 42H6v-6.4l25.2-25.2Zm-5.35-1.05-1.1-1.1 2.2 2.2Z" />
</svg>
);
29 changes: 26 additions & 3 deletions components/form-builder/lexical-editor/Editor.tsx
@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { LexicalComposer } from "@lexical/react/LexicalComposer";
Expand All @@ -17,6 +17,8 @@ import {
TRANSFORMERS,
} from "@lexical/markdown";
import { TabEscape } from "./plugins/TabEscape";
import FloatingLinkEditorPlugin from "./plugins/FloatingLinkEditorPlugin";
import { t } from "i18next";

const RichTextWrapper = styled.div`
height: 100%;
Expand All @@ -39,6 +41,18 @@ export const Editor = ({
onChange: (value: string) => void;
autoFocusEditor?: boolean;
}) => {
const [floatingAnchorElem, setFloatingAnchorElem] = useState<HTMLDivElement | undefined>(
undefined
);

const editorId = "editor-" + Math.random().toString(36).substr(2, 9);

const onRef = (_floatingAnchorElem: HTMLDivElement) => {
if (_floatingAnchorElem !== null) {
setFloatingAnchorElem(_floatingAnchorElem);
}
};

if (typeof content !== "string") {
content = "";
}
Expand All @@ -58,9 +72,17 @@ export const Editor = ({
},
}}
>
<Toolbar />
<Toolbar editorId={editorId} />
<RichTextPlugin
contentEditable={<ContentEditable className="editor-input" />}
contentEditable={
<div className="editor relative" ref={onRef}>
<ContentEditable
className="editor-input"
id={editorId}
ariaLabel={t("RichTextEditor")}
/>
</div>
}
placeholder={""}
/>
<FocusPlugin autoFocusEditor={autoFocusEditor} />
Expand All @@ -74,6 +96,7 @@ export const Editor = ({
}}
/>
<LinkPlugin />
<FloatingLinkEditorPlugin anchorElem={floatingAnchorElem} />
<ListPlugin />
<TabEscape />
</LexicalComposer>
Expand Down
48 changes: 30 additions & 18 deletions components/form-builder/lexical-editor/Toolbar.tsx
Expand Up @@ -2,14 +2,14 @@ import React, { useState, useCallback, useEffect, useRef, KeyboardEvent } from "
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { $isHeadingNode, $createHeadingNode } from "@lexical/rich-text";
import { mergeRegister, $getNearestNodeOfType } from "@lexical/utils";
import { LinkEditor } from "./plugins/LinkEditor";
import { Looks3 } from "@styled-icons/material/Looks3";
import { LooksTwo } from "@styled-icons/material/LooksTwo";
import { FormatBold } from "@styled-icons/material/FormatBold";
import { FormatItalic } from "@styled-icons/material/FormatItalic";
import { Link } from "@styled-icons/material/Link";
import { FormatListBulleted } from "@styled-icons/material/FormatListBulleted";
import { FormatListNumbered } from "@styled-icons/material/FormatListNumbered";
import { TOGGLE_LINK_COMMAND } from "@lexical/link";

import {
$isListNode,
Expand All @@ -29,6 +29,7 @@ import {

import { $wrapNodes } from "@lexical/selection";
import styled from "styled-components";
import { sanitizeUrl } from "./utils/sanitizeUrl";

const blockTypeToBlockName = {
bullet: "Bulleted List",
Expand Down Expand Up @@ -74,14 +75,24 @@ const ToolbarContainer = styled.div`
const LowPriority = 1;
type HeadingTagType = "h2" | "h3" | "h4" | "h5";

export const Toolbar = () => {
export const Toolbar = ({ editorId }: { editorId: string }) => {
const [editor] = useLexicalComposerContext();
const [isBold, setIsBold] = useState(false);
const [isItalic, setIsItalic] = useState(false);
const [isLink] = useState(false);
const [, setSelectedElementKey] = useState("");
const [blockType, setBlockType] = useState("paragraph");

const [isEditable] = useState(() => editor.isEditable());

const insertLink = useCallback(() => {
if (!isLink) {
editor.dispatchCommand(TOGGLE_LINK_COMMAND, sanitizeUrl("https://"));
} else {
editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
}
}, [editor, isLink]);

const [items] = useState([
{ id: 1, txt: "heading2" },
{ id: 2, txt: "heading3" },
Expand Down Expand Up @@ -229,7 +240,7 @@ export const Toolbar = () => {
<ToolbarContainer
role="toolbar"
aria-label="Text formatting"
aria-controls=""
aria-controls={editorId}
onKeyDown={handleNav}
>
<button
Expand Down Expand Up @@ -330,21 +341,22 @@ export const Toolbar = () => {
<FormatListNumbered size={20} />
</button>

<LinkEditor>
<button
tabIndex={currentFocusIndex == 6 ? 0 : -1}
ref={(el) => {
const index = "button-6" as unknown as number;
if (el && itemsRef.current) {
itemsRef.current[index] = el;
}
}}
className={"toolbar-item " + (isLink ? "active" : "")}
aria-label="Format Link"
>
<Link size={20} />
</button>
</LinkEditor>
<button
tabIndex={currentFocusIndex == 6 ? 0 : -1}
ref={(el) => {
const index = "button-6" as unknown as number;
if (el && itemsRef.current) {
itemsRef.current[index] = el;
}
}}
disabled={!isEditable}
onClick={insertLink}
className={"toolbar-item " + (isLink ? "active" : "")}
aria-label="Insert link"
title="Insert link"
>
<Link size={20} />
</button>
</ToolbarContainer>
</>
);
Expand Down

0 comments on commit abb7be0

Please sign in to comment.