refactor: refactor NoteTags for better readability

This commit is contained in:
Antonella Sgarlatta
2021-05-31 14:38:44 -03:00
parent b7c2fa0b60
commit b171e48c57

View File

@@ -4,7 +4,7 @@ import { toDirective } from './utils';
import { Icon } from './Icon';
import { AutocompleteTagInput } from './AutocompleteTagInput';
import { WebApplication } from '@/ui_models/application';
import { useEffect, useRef, useState } from 'preact/hooks';
import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
import { SNTag } from '@standardnotes/snjs';
type Props = {
@@ -21,15 +21,14 @@ const NoteTags = observer(({ application, appState }: Props) => {
const { tags, tagsContainerPosition, tagsContainerMaxWidth } =
appState.activeNote;
const [overflowedTagsCount, setOverflowedTagsCount] = useState(0);
const [overflowCountPosition, setOverflowCountPosition] = useState(0);
const [tagsContainerCollapsed, setTagsContainerCollapsed] = useState(true);
const [containerHeight, setContainerHeight] = useState(TAGS_ROW_HEIGHT);
const [tagsContainerHeight, setTagsContainerHeight] =
useState(TAGS_ROW_HEIGHT);
const [overflowCountPosition, setOverflowCountPosition] = useState(0);
const [overflowCount, setOverflowCount] = useState(0);
const containerRef = useRef<HTMLDivElement>();
const tagsContainerRef = useRef<HTMLDivElement>();
const tagsRef = useRef<HTMLButtonElement[]>([]);
tagsRef.current = [];
const onTagBackspacePress = async (tag: SNTag) => {
await appState.activeNote.removeTagFromActiveNote(tag);
@@ -40,46 +39,68 @@ const NoteTags = observer(({ application, appState }: Props) => {
};
const expandTags = () => {
setContainerHeight(tagsContainerRef.current.scrollHeight);
setTagsContainerCollapsed(false);
};
const isTagOverflowed = useCallback(
(tagElement?: HTMLButtonElement): boolean | undefined => {
if (!tagElement) {
return;
}
if (!tagsContainerCollapsed) {
return false;
}
return tagElement.getBoundingClientRect().top >= MIN_OVERFLOW_TOP;
},
[tagsContainerCollapsed]
);
const reloadOverflowCountPosition = useCallback(() => {
const firstOverflowedTagIndex = tagsRef.current.findIndex((tagElement) =>
isTagOverflowed(tagElement)
);
if (!tagsContainerCollapsed || firstOverflowedTagIndex < 1) {
return;
}
const previousTagRect =
tagsRef.current[firstOverflowedTagIndex - 1].getBoundingClientRect();
const position =
previousTagRect.right - (tagsContainerPosition ?? 0) + TAGS_RIGHT_MARGIN;
setOverflowCountPosition(position);
}, [isTagOverflowed, tagsContainerCollapsed, tagsContainerPosition]);
const reloadTagsContainerHeight = useCallback(() => {
const height = tagsContainerCollapsed
? TAGS_ROW_HEIGHT
: tagsContainerRef.current.scrollHeight;
setTagsContainerHeight(height);
}, [tagsContainerCollapsed]);
const reloadOverflowCount = useCallback(() => {
const count = tagsRef.current.filter((tagElement) =>
isTagOverflowed(tagElement)
).length;
setOverflowCount(count);
}, [isTagOverflowed]);
useEffect(() => {
appState.activeNote.reloadTagsContainerLayout();
let overflowCount = 0;
for (const [index, tagElement] of tagsRef.current.entries()) {
if (tagElement.getBoundingClientRect().top >= MIN_OVERFLOW_TOP) {
if (overflowCount === 0) {
setOverflowCountPosition(
tagsRef.current[index - 1].getBoundingClientRect().right -
(tagsContainerPosition ?? 0) +
TAGS_RIGHT_MARGIN
);
}
overflowCount += 1;
}
}
setOverflowedTagsCount(overflowCount);
if (!tagsContainerCollapsed) {
setContainerHeight(tagsContainerRef.current.scrollHeight);
}
reloadOverflowCountPosition();
reloadTagsContainerHeight();
reloadOverflowCount();
}, [
appState.activeNote,
reloadOverflowCountPosition,
reloadTagsContainerHeight,
reloadOverflowCount,
tags,
tagsContainerCollapsed,
tagsContainerPosition,
]);
const tagClass = `bg-contrast border-0 rounded text-xs color-text py-1 pr-2 flex items-center
mt-2 mr-2 cursor-pointer hover:bg-secondary-contrast focus:bg-secondary-contrast`;
return (
<div
className="flex"
ref={containerRef}
style={{ height: containerHeight }}
>
<div className="flex" style={{ height: tagsContainerHeight }}>
<div
ref={tagsContainerRef}
className={`absolute flex flex-wrap pl-1 -ml-1 ${
@@ -121,14 +142,14 @@ const NoteTags = observer(({ application, appState }: Props) => {
tagsRef={tagsRef}
/>
</div>
{overflowedTagsCount > 1 && tagsContainerCollapsed && (
{overflowCount > 1 && tagsContainerCollapsed && (
<button
type="button"
className={`${tagClass} pl-2 absolute`}
style={{ left: overflowCountPosition }}
onClick={expandTags}
>
+{overflowedTagsCount}
+{overflowCount}
</button>
)}
</div>