feat: show button to remove note on focus

This commit is contained in:
Antonella Sgarlatta
2021-06-02 20:00:42 -03:00
parent 3fb3425aa2
commit 093acd1519

View File

@@ -3,8 +3,6 @@ import { FunctionalComponent } from 'preact';
import { useRef, useState } from 'preact/hooks'; import { useRef, useState } from 'preact/hooks';
import { AppState } from '@/ui_models/app_state'; import { AppState } from '@/ui_models/app_state';
import { SNTag } from '@standardnotes/snjs/dist/@types'; import { SNTag } from '@standardnotes/snjs/dist/@types';
import { useEffect } from 'react';
import { useCloseOnBlur, useCloseOnClickOutside } from './utils';
type Props = { type Props = {
appState: AppState; appState: AppState;
@@ -16,14 +14,8 @@ export const NoteTag: FunctionalComponent<Props> = ({ appState, tag }) => {
tagsContainerMaxWidth, tagsContainerMaxWidth,
} = appState.activeNote; } = appState.activeNote;
const [contextMenuOpen, setContextMenuOpen] = useState(false); const [showDeleteButton, setShowDeleteButton] = useState(false);
const [contextMenuPosition, setContextMenuPosition] = useState({ top: 0, left: 0 }); const deleteTagRef = useRef<HTMLButtonElement>();
const contextMenuRef = useRef<HTMLDivElement>();
const tagRef = useRef<HTMLButtonElement>();
const [closeOnBlur] = useCloseOnBlur(contextMenuRef, setContextMenuOpen);
useCloseOnClickOutside(contextMenuRef, setContextMenuOpen);
const deleteTag = () => { const deleteTag = () => {
appState.activeNote.removeTagFromActiveNote(tag); appState.activeNote.removeTagFromActiveNote(tag);
@@ -33,66 +25,54 @@ export const NoteTag: FunctionalComponent<Props> = ({ appState, tag }) => {
appState.setSelectedTag(tag); appState.setSelectedTag(tag);
}; };
const contextMenuListener = (event: MouseEvent) => { const onFocus = () => {
event.preventDefault(); setShowDeleteButton(true);
setContextMenuPosition({
top: event.clientY,
left: event.clientX,
});
setContextMenuOpen(true);
}; };
useEffect(() => { const onBlur = (event: FocusEvent) => {
tagRef.current.addEventListener('contextmenu', contextMenuListener); const relatedTarget = event.relatedTarget as Node;
return () => { if (relatedTarget !== deleteTagRef.current) {
tagRef.current.removeEventListener('contextmenu', contextMenuListener); setShowDeleteButton(false);
}; }
}, []); };
return ( return (
<> <button
<button ref={(element) => {
ref={(element) => { if (element) {
if (element) { appState.activeNote.setTagElement(tag, element);
appState.activeNote.setTagElement(tag, element); }
tagRef.current = element; }}
} className="sn-tag pl-1 pr-2 mr-2"
}} style={{ maxWidth: tagsContainerMaxWidth }}
className="sn-tag pl-1 pr-2 mr-2" onClick={onTagClick}
style={{ maxWidth: tagsContainerMaxWidth }} onKeyUp={(event) => {
onClick={onTagClick} if (event.key === 'Backspace') {
onKeyUp={(event) => { deleteTag();
if (event.key === 'Backspace') { }
deleteTag(); }}
} onFocus={onFocus}
}} onBlur={onBlur}
onBlur={closeOnBlur} >
> <Icon type="hashtag" className="sn-icon--small color-neutral mr-1" />
<Icon type="hashtag" className="sn-icon--small mr-1 color-info" /> <span className="whitespace-nowrap overflow-hidden overflow-ellipsis">
<span className="whitespace-nowrap overflow-hidden overflow-ellipsis"> {tag.title}
{tag.title} </span>
</span> {showDeleteButton && (
</button> <button
{contextMenuOpen && ( ref={deleteTagRef}
<div type="button"
ref={contextMenuRef} className="ml-2 -mr-1 border-0 p-0 bg-transparent cursor-pointer flex"
className="sn-dropdown sn-dropdown--small max-h-120 max-w-xs flex flex-col py-2 overflow-y-scroll fixed" onFocus={onFocus}
style={{ onBlur={onBlur}
...contextMenuPosition onClick={deleteTag}
}}
> >
<button <Icon
type="button" type="close"
className="sn-dropdown-item" className="sn-icon--small color-neutral hover:color-info"
onClick={deleteTag} />
> </button>
<div className="flex items-center">
<Icon type="close" className="color-danger mr-2" />
<span className="color-danger">Remove tag</span>
</div>
</button>
</div>
)} )}
</> </button>
); );
}; };