refactor: extract shared logic to active note state

This commit is contained in:
Antonella Sgarlatta
2021-06-02 17:57:37 -03:00
parent 3db87099e0
commit 6fb68d2255
8 changed files with 184 additions and 164 deletions

View File

@@ -1,6 +1,6 @@
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { SNTag } from '@standardnotes/snjs'; import { SNTag } from '@standardnotes/snjs';
import { FunctionalComponent, RefObject } from 'preact'; import { FunctionalComponent } from 'preact';
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
import { Icon } from './Icon'; import { Icon } from './Icon';
import { Disclosure, DisclosurePanel } from '@reach/disclosure'; import { Disclosure, DisclosurePanel } from '@reach/disclosure';
@@ -10,15 +10,13 @@ import { AppState } from '@/ui_models/app_state';
type Props = { type Props = {
application: WebApplication; application: WebApplication;
appState: AppState; appState: AppState;
tagsRef: RefObject<HTMLButtonElement[]>;
}; };
export const AutocompleteTagInput: FunctionalComponent<Props> = ({ export const AutocompleteTagInput: FunctionalComponent<Props> = ({
application, application,
appState, appState,
tagsRef,
}) => { }) => {
const { tags, tagsContainerMaxWidth, tagsOverflowed } = appState.activeNote; const { tagElements, tags, tagsContainerMaxWidth, tagsOverflowed } = appState.activeNote;
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [dropdownVisible, setDropdownVisible] = useState(false); const [dropdownVisible, setDropdownVisible] = useState(false);
@@ -85,13 +83,9 @@ export const AutocompleteTagInput: FunctionalComponent<Props> = ({
}; };
const reloadInputOverflowed = useCallback(() => { const reloadInputOverflowed = useCallback(() => {
let overflowed = false; const overflowed = !tagsOverflowed && appState.activeNote.isElementOverflowed(inputRef.current);
if (!tagsOverflowed && tagsRef.current && tagsRef.current.length > 0) {
const firstTagTop = tagsRef.current[0].offsetTop;
overflowed = inputRef.current.offsetTop > firstTagTop;
}
appState.activeNote.setInputOverflowed(overflowed); appState.activeNote.setInputOverflowed(overflowed);
}, [appState.activeNote, tagsOverflowed, tagsRef]); }, [appState.activeNote, tagsOverflowed]);
useEffect(() => { useEffect(() => {
reloadInputOverflowed(); reloadInputOverflowed();
@@ -124,10 +118,9 @@ export const AutocompleteTagInput: FunctionalComponent<Props> = ({
if ( if (
event.key === 'Backspace' && event.key === 'Backspace' &&
searchQuery === '' && searchQuery === '' &&
tagsRef.current && tagElements.length > 0
tagsRef.current.length > 1
) { ) {
tagsRef.current[tagsRef.current.length - 1].focus(); tagElements[tagElements.length - 1]?.focus();
} }
}} }}
/> />

View File

@@ -1,34 +1,34 @@
import { Icon } from './Icon'; import { Icon } from './Icon';
import { FunctionalComponent, RefObject } from 'preact'; import { FunctionalComponent, RefObject } from 'preact';
import { useRef, useState } from 'preact/hooks'; import { useCallback, 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';
type Props = { type Props = {
appState: AppState; appState: AppState;
index: number;
tagsRef: RefObject<HTMLButtonElement[]>;
tag: SNTag; tag: SNTag;
overflowed: boolean; overflowButtonRef: RefObject<HTMLButtonElement>;
maxWidth: number | 'auto';
}; };
export const NoteTag: FunctionalComponent<Props> = ({ export const NoteTag: FunctionalComponent<Props> = ({ appState, tag, overflowButtonRef }) => {
appState, const {
index, tags,
tagsRef, tagsContainerMaxWidth,
tag, } = appState.activeNote;
overflowed,
maxWidth, const [overflowed, setOverflowed] = useState(false);
}) => {
const [showDeleteButton, setShowDeleteButton] = useState(false); const [showDeleteButton, setShowDeleteButton] = useState(false);
const deleteTagRef = useRef<HTMLButtonElement>(); const deleteTagRef = useRef<HTMLButtonElement>();
const deleteTag = async () => { const deleteTag = async () => {
await appState.activeNote.removeTagFromActiveNote(tag); await appState.activeNote.removeTagFromActiveNote(tag);
const previousTag = appState.activeNote.getPreviousTag(tag);
if (index > 0 && tagsRef.current) { if (previousTag) {
tagsRef.current[index - 1].focus(); const previousTagElement = appState.activeNote.getTagElement(previousTag);
previousTagElement?.focus();
} }
}; };
@@ -42,21 +42,33 @@ export const NoteTag: FunctionalComponent<Props> = ({
}; };
const onBlur = (event: FocusEvent) => { const onBlur = (event: FocusEvent) => {
appState.activeNote.setTagFocused(false); const relatedTarget = event.relatedTarget as Node;
if ((event.relatedTarget as Node) !== deleteTagRef.current) { if (relatedTarget === overflowButtonRef.current) {
(event.target as HTMLButtonElement).focus();
} else if (relatedTarget !== deleteTagRef.current) {
appState.activeNote.setTagFocused(false);
setShowDeleteButton(false); setShowDeleteButton(false);
} }
}; };
const reloadOverflowed = useCallback(() => {
const overflowed = appState.activeNote.isTagOverflowed(tag);
setOverflowed(overflowed);
}, [appState.activeNote, tag]);
useEffect(() => {
reloadOverflowed();
}, [reloadOverflowed, tags, tagsContainerMaxWidth]);
return ( return (
<button <button
ref={(element) => { ref={(element) => {
if (element && tagsRef.current) { if (element) {
tagsRef.current[index] = element; appState.activeNote.setTagElement(tag, element);
} }
}} }}
className="sn-tag pl-1 pr-2 mr-2" className="sn-tag pl-1 pr-2 mr-2"
style={{ maxWidth }} style={{ maxWidth: tagsContainerMaxWidth }}
onClick={onTagClick} onClick={onTagClick}
onKeyUp={(event) => { onKeyUp={(event) => {
if (event.key === 'Backspace') { if (event.key === 'Backspace') {

View File

@@ -4,7 +4,6 @@ import { toDirective, useCloseOnClickOutside } from './utils';
import { AutocompleteTagInput } from './AutocompleteTagInput'; import { AutocompleteTagInput } from './AutocompleteTagInput';
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
import { SNTag } from '@standardnotes/snjs';
import { NoteTag } from './NoteTag'; import { NoteTag } from './NoteTag';
type Props = { type Props = {
@@ -15,7 +14,9 @@ type Props = {
const NoteTagsContainer = observer(({ application, appState }: Props) => { const NoteTagsContainer = observer(({ application, appState }: Props) => {
const { const {
inputOverflowed, inputOverflowed,
overflowCountPosition,
overflowedTagsCount, overflowedTagsCount,
tagElements,
tags, tags,
tagsContainerMaxWidth, tagsContainerMaxWidth,
tagsContainerExpanded, tagsContainerExpanded,
@@ -23,15 +24,9 @@ const NoteTagsContainer = observer(({ application, appState }: Props) => {
} = appState.activeNote; } = appState.activeNote;
const [expandedContainerHeight, setExpandedContainerHeight] = useState(0); const [expandedContainerHeight, setExpandedContainerHeight] = useState(0);
const [lastVisibleTagIndex, setLastVisibleTagIndex] =
useState<number | null>(null);
const [overflowCountPosition, setOverflowCountPosition] = useState(0);
const containerRef = useRef<HTMLDivElement>();
const tagsContainerRef = useRef<HTMLDivElement>(); const tagsContainerRef = useRef<HTMLDivElement>();
const tagsRef = useRef<HTMLButtonElement[]>([]); const overflowButtonRef = useRef<HTMLButtonElement>();
tagsRef.current = [];
useCloseOnClickOutside(tagsContainerRef, (expanded: boolean) => { useCloseOnClickOutside(tagsContainerRef, (expanded: boolean) => {
if (tagsContainerExpanded) { if (tagsContainerExpanded) {
@@ -39,88 +34,29 @@ const NoteTagsContainer = observer(({ application, appState }: Props) => {
} }
}); });
const isTagOverflowed = useCallback( const reloadExpandedContainerHeight = useCallback(() => {
(tagElement?: HTMLButtonElement): boolean | undefined => {
if (!tagElement) {
return;
}
if (tagsContainerExpanded) {
return false;
}
const firstTagTop = tagsRef.current[0].offsetTop;
return tagElement.offsetTop > firstTagTop;
},
[tagsContainerExpanded]
);
const reloadLastVisibleTagIndex = useCallback(() => {
if (tagsContainerExpanded) {
return tags.length - 1;
}
const firstOverflowedTagIndex = tagsRef.current.findIndex((tagElement) =>
isTagOverflowed(tagElement)
);
if (firstOverflowedTagIndex > -1) {
setLastVisibleTagIndex(firstOverflowedTagIndex - 1);
} else {
setLastVisibleTagIndex(null);
}
}, [isTagOverflowed, tags, tagsContainerExpanded]);
const reloadExpandedContainersHeight = useCallback(() => {
setExpandedContainerHeight(tagsContainerRef.current.scrollHeight); setExpandedContainerHeight(tagsContainerRef.current.scrollHeight);
}, []); }, []);
const reloadOverflowCount = useCallback(() => { useEffect(() => {
const count = tagsRef.current.filter((tagElement) =>
isTagOverflowed(tagElement)
).length;
appState.activeNote.setOverflowedTagsCount(count);
}, [appState.activeNote, isTagOverflowed]);
const reloadOverflowCountPosition = useCallback(() => {
if (tagsContainerExpanded || !lastVisibleTagIndex) {
return;
}
if (tagsRef.current[lastVisibleTagIndex]) {
const {
offsetLeft: lastVisibleTagLeft,
clientWidth: lastVisibleTagWidth,
} = tagsRef.current[lastVisibleTagIndex];
setOverflowCountPosition(lastVisibleTagLeft + lastVisibleTagWidth);
}
}, [lastVisibleTagIndex, tagsContainerExpanded]);
const expandTags = () => {
appState.activeNote.setTagsContainerExpanded(true);
};
const reloadTagsContainerLayout = useCallback(() => {
appState.activeNote.reloadTagsContainerLayout(); appState.activeNote.reloadTagsContainerLayout();
reloadLastVisibleTagIndex(); reloadExpandedContainerHeight();
reloadExpandedContainersHeight();
reloadOverflowCount();
reloadOverflowCountPosition();
}, [ }, [
appState.activeNote, appState.activeNote,
reloadLastVisibleTagIndex, reloadExpandedContainerHeight,
reloadExpandedContainersHeight, tags,
reloadOverflowCount, tagsContainerMaxWidth,
reloadOverflowCountPosition,
]); ]);
useEffect(() => {
reloadTagsContainerLayout();
}, [reloadTagsContainerLayout, tags, tagsContainerMaxWidth]);
useEffect(() => { useEffect(() => {
let tagResizeObserver: ResizeObserver; let tagResizeObserver: ResizeObserver;
if (ResizeObserver) { if (ResizeObserver) {
tagResizeObserver = new ResizeObserver(() => { tagResizeObserver = new ResizeObserver(() => {
reloadTagsContainerLayout(); appState.activeNote.reloadTagsContainerLayout();
reloadExpandedContainerHeight();
}); });
tagsRef.current.forEach((tagElement) => tagElements.forEach(
tagResizeObserver.observe(tagElement) (tagElement) => tagElement && tagResizeObserver.observe(tagElement)
); );
} }
@@ -129,14 +65,13 @@ const NoteTagsContainer = observer(({ application, appState }: Props) => {
tagResizeObserver.disconnect(); tagResizeObserver.disconnect();
} }
}; };
}, [reloadTagsContainerLayout]); }, [appState.activeNote, reloadExpandedContainerHeight, tagElements]);
return ( return (
<div <div
className={`flex transition-height duration-150 relative ${ className={`flex transition-height duration-150 relative ${
inputOverflowed ? 'h-18' : 'h-9' inputOverflowed ? 'h-18' : 'h-9'
}`} }`}
ref={containerRef}
style={tagsContainerExpanded ? { height: expandedContainerHeight } : {}} style={tagsContainerExpanded ? { height: expandedContainerHeight } : {}}
> >
<div <div
@@ -148,31 +83,22 @@ const NoteTagsContainer = observer(({ application, appState }: Props) => {
maxWidth: tagsContainerMaxWidth, maxWidth: tagsContainerMaxWidth,
}} }}
> >
{tags.map((tag: SNTag, index: number) => ( {tags.map((tag) => (
<NoteTag <NoteTag
key={tag.uuid}
appState={appState} appState={appState}
tagsRef={tagsRef}
index={index}
tag={tag} tag={tag}
maxWidth={tagsContainerMaxWidth} overflowButtonRef={overflowButtonRef}
overflowed={
!tagsContainerExpanded &&
!!lastVisibleTagIndex &&
index > lastVisibleTagIndex
}
/> />
))} ))}
<AutocompleteTagInput <AutocompleteTagInput application={application} appState={appState} />
application={application}
appState={appState}
tagsRef={tagsRef}
/>
</div> </div>
{tagsOverflowed && ( {tagsOverflowed && (
<button <button
ref={overflowButtonRef}
type="button" type="button"
className="sn-tag ml-1 px-2 absolute" className="sn-tag ml-1 absolute"
onClick={expandTags} onClick={() => appState.activeNote.setTagsContainerExpanded(true)}
style={{ left: overflowCountPosition }} style={{ left: overflowCountPosition }}
> >
+{overflowedTagsCount} +{overflowedTagsCount}

View File

@@ -54,7 +54,7 @@ class PanelResizerCtrl implements PanelResizerScope {
index!: number index!: number
minWidth!: number minWidth!: number
onResizeFinish!: () => ResizeFinishCallback onResizeFinish!: () => ResizeFinishCallback
onWidthEvent?: () => () => void onMouseMoveEvent?: () => () => void
panelId!: string panelId!: string
property!: PanelSide property!: PanelSide
@@ -104,7 +104,7 @@ class PanelResizerCtrl implements PanelResizerScope {
$onDestroy() { $onDestroy() {
(this.onResizeFinish as any) = undefined; (this.onResizeFinish as any) = undefined;
(this.onWidthEvent as any) = undefined; (this.onMouseMoveEvent as any) = undefined;
(this.control as any) = undefined; (this.control as any) = undefined;
window.removeEventListener(WINDOW_EVENT_RESIZE, this.handleResize); window.removeEventListener(WINDOW_EVENT_RESIZE, this.handleResize);
document.removeEventListener(MouseEventType.Move, this.onMouseMove); document.removeEventListener(MouseEventType.Move, this.onMouseMove);
@@ -245,13 +245,13 @@ class PanelResizerCtrl implements PanelResizerScope {
return; return;
} }
event.preventDefault(); event.preventDefault();
if (this.onMouseMoveEvent) {
this.onMouseMoveEvent()();
}
if (this.property && this.property === PanelSide.Left) { if (this.property && this.property === PanelSide.Left) {
this.handleLeftEvent(event); this.handleLeftEvent(event);
} else { } else {
this.handleWidthEvent(event); this.handleWidthEvent(event);
if (this.onWidthEvent) {
this.onWidthEvent()();
}
} }
} }
@@ -393,7 +393,7 @@ export class PanelResizer extends WebDirective {
index: '=', index: '=',
minWidth: '=', minWidth: '=',
onResizeFinish: '&', onResizeFinish: '&',
onWidthEvent: '&', onMouseMoveEvent: '&',
panelId: '=', panelId: '=',
property: '=' property: '='
}; };

View File

@@ -14,10 +14,12 @@ import { AppState } from './app_state';
export class ActiveNoteState { export class ActiveNoteState {
inputOverflowed = false; inputOverflowed = false;
overflowCountPosition = 0;
overflowedTagsCount = 0; overflowedTagsCount = 0;
tagElements: (HTMLButtonElement | undefined)[] = [];
tagFocused = false;
tags: SNTag[] = []; tags: SNTag[] = [];
tagsContainerMaxWidth: number | 'auto' = 0; tagsContainerMaxWidth: number | 'auto' = 0;
tagFocused = false;
tagsContainerExpanded = false; tagsContainerExpanded = false;
constructor( constructor(
@@ -27,29 +29,31 @@ export class ActiveNoteState {
) { ) {
makeObservable(this, { makeObservable(this, {
inputOverflowed: observable, inputOverflowed: observable,
overflowCountPosition: observable,
overflowedTagsCount: observable, overflowedTagsCount: observable,
tags: observable, tagElements: observable,
tagFocused: observable, tagFocused: observable,
tags: observable,
tagsContainerExpanded: observable, tagsContainerExpanded: observable,
tagsContainerMaxWidth: observable, tagsContainerMaxWidth: observable,
tagsOverflowed: computed, tagsOverflowed: computed,
setInputOverflowed: action, setInputOverflowed: action,
setOverflowCountPosition: action,
setOverflowedTagsCount: action, setOverflowedTagsCount: action,
setTagElement: action,
setTagFocused: action, setTagFocused: action,
setTags: action,
setTagsContainerExpanded: action, setTagsContainerExpanded: action,
setTagsContainerMaxWidth: action, setTagsContainerMaxWidth: action,
reloadTags: action, reloadTags: action,
}); });
appEventListeners.push( appEventListeners.push(
application.streamItems( application.streamItems(ContentType.Tag, () => {
ContentType.Tag, this.reloadTags();
() => { })
this.reloadTags();
}
)
); );
} }
@@ -65,14 +69,33 @@ export class ActiveNoteState {
this.inputOverflowed = overflowed; this.inputOverflowed = overflowed;
} }
setOverflowCountPosition(position: number): void {
this.overflowCountPosition = position;
}
setOverflowedTagsCount(count: number): void { setOverflowedTagsCount(count: number): void {
this.overflowedTagsCount = count; this.overflowedTagsCount = count;
} }
setTagElement(tag: SNTag, element: HTMLButtonElement): void {
const tagIndex = this.getTagIndex(tag);
if (tagIndex > -1) {
this.tagElements.splice(tagIndex, 1, element);
}
}
setTagFocused(focused: boolean): void { setTagFocused(focused: boolean): void {
this.tagFocused = focused; this.tagFocused = focused;
} }
setTagElements(elements: (HTMLButtonElement | undefined)[]): void {
this.tagElements = elements;
}
setTags(tags: SNTag[]): void {
this.tags = tags;
}
setTagsContainerExpanded(expanded: boolean): void { setTagsContainerExpanded(expanded: boolean): void {
this.tagsContainerExpanded = expanded; this.tagsContainerExpanded = expanded;
} }
@@ -81,28 +104,86 @@ export class ActiveNoteState {
this.tagsContainerMaxWidth = width; this.tagsContainerMaxWidth = width;
} }
getTagElement(tag: SNTag): HTMLButtonElement | undefined {
const tagIndex = this.getTagIndex(tag);
if (tagIndex > -1 && this.tagElements.length > tagIndex) {
return this.tagElements[tagIndex];
}
}
getTagIndex(tag: SNTag): number {
return this.tags.findIndex(t => t.uuid === tag.uuid);
}
getPreviousTag(tag: SNTag): SNTag | undefined {
const previousTagIndex = this.getTagIndex(tag) - 1;
if (previousTagIndex > -1 && this.tags.length > previousTagIndex) {
return this.tags[previousTagIndex];
}
}
isElementOverflowed(element: HTMLElement): boolean {
if (
this.tagElements.length === 0 ||
!this.tagElements[0]
) {
return false;
}
const firstTagTop = this.tagElements[0].offsetTop;
return element.offsetTop > firstTagTop;
}
isTagOverflowed(tag: SNTag): boolean {
const tagElement = this.getTagElement(tag);
return tagElement ? this.isElementOverflowed(tagElement) : false;
}
reloadTags(): void { reloadTags(): void {
const { activeNote } = this; const { activeNote } = this;
if (activeNote) { if (activeNote) {
this.tags = this.application.getSortedTagsForNote(activeNote); const tags = this.application.getSortedTagsForNote(activeNote);
} const tagElements: (HTMLButtonElement | undefined)[] = [];
this.setTags(tags);
this.setTagElements(tagElements.fill(undefined, tags.length));
}
}
reloadOverflowCountPosition(): void {
const lastVisibleTagIndex = this.tagElements.findIndex(tagElement => tagElement && this.isElementOverflowed(tagElement)) - 1;
if (lastVisibleTagIndex > -1 && this.tagElements.length > lastVisibleTagIndex) {
const lastVisibleTagElement = this.tagElements[lastVisibleTagIndex];
if (lastVisibleTagElement) {
const { offsetLeft, offsetWidth } = lastVisibleTagElement;
this.setOverflowCountPosition(offsetLeft + offsetWidth);
}
}
}
reloadOverflowedTagsCount(): void {
const count = this.tagElements.filter((tagElement) =>
tagElement && this.isElementOverflowed(tagElement)
).length;
this.setOverflowedTagsCount(count);
}
reloadTagsContainerMaxWidth(): void {
const EDITOR_ELEMENT_ID = 'editor-column';
const defaultFontSize = parseFloat(window.getComputedStyle(
document.documentElement
).fontSize);
const overflowMargin = defaultFontSize * 5;
const editorWidth = document.getElementById(EDITOR_ELEMENT_ID)?.clientWidth;
if (editorWidth) {
this.appState.activeNote.setTagsContainerMaxWidth(
editorWidth - overflowMargin
);
}
} }
reloadTagsContainerLayout(): void { reloadTagsContainerLayout(): void {
const EDITOR_ELEMENT_ID = 'editor-column'; this.reloadTagsContainerMaxWidth();
const defaultFontSize = window.getComputedStyle( this.reloadOverflowedTagsCount();
document.documentElement this.reloadOverflowCountPosition();
).fontSize;
const containerMargins = parseFloat(defaultFontSize) * 6;
const deleteButtonMargin = this.tagFocused ? parseFloat(defaultFontSize) * 1.25 : 0;
const editorWidth =
document.getElementById(EDITOR_ELEMENT_ID)?.clientWidth;
if (editorWidth) {
this.appState.activeNote.setTagsContainerMaxWidth(
editorWidth - containerMargins + deleteButtonMargin
);
}
} }
async addTagToActiveNote(tag: SNTag): Promise<void> { async addTagToActiveNote(tag: SNTag): Promise<void> {

View File

@@ -169,6 +169,6 @@
default-width="300" default-width="300"
hoverable="true" hoverable="true"
on-resize-finish="self.onPanelResize" on-resize-finish="self.onPanelResize"
on-width-event="self.onPanelWidthEvent" on-mouse-move-event="self.onPanelMouseMoveEvent"
panel-id="'notes-column'" panel-id="'notes-column'"
) )

View File

@@ -93,7 +93,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesCtrlState> {
}; };
this.onWindowResize = this.onWindowResize.bind(this); this.onWindowResize = this.onWindowResize.bind(this);
this.onPanelResize = this.onPanelResize.bind(this); this.onPanelResize = this.onPanelResize.bind(this);
this.onPanelWidthEvent = this.onPanelWidthEvent.bind(this); this.onPanelMouseMoveEvent = this.onPanelMouseMoveEvent.bind(this);
window.addEventListener('resize', this.onWindowResize, true); window.addEventListener('resize', this.onWindowResize, true);
this.registerKeyboardShortcuts(); this.registerKeyboardShortcuts();
this.autorun(async () => { this.autorun(async () => {
@@ -134,7 +134,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesCtrlState> {
window.removeEventListener('resize', this.onWindowResize, true); window.removeEventListener('resize', this.onWindowResize, true);
(this.onWindowResize as any) = undefined; (this.onWindowResize as any) = undefined;
(this.onPanelResize as any) = undefined; (this.onPanelResize as any) = undefined;
(this.onPanelWidthEvent as any) = undefined; (this.onPanelMouseMoveEvent as any) = undefined;
this.newNoteKeyObserver(); this.newNoteKeyObserver();
this.nextNoteKeyObserver(); this.nextNoteKeyObserver();
this.previousNoteKeyObserver(); this.previousNoteKeyObserver();
@@ -659,8 +659,8 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesCtrlState> {
); );
} }
onPanelWidthEvent(): void { onPanelMouseMoveEvent(): void {
this.appState.activeNote.reloadTagsContainerLayout(); this.appState.activeNote.reloadTagsContainerMaxWidth();
} }
paginate() { paginate() {

View File

@@ -162,6 +162,10 @@
line-height: 2.25rem; line-height: 2.25rem;
} }
.w-0 {
width: 0;
}
.w-3\.5 { .w-3\.5 {
width: 0.875rem; width: 0.875rem;
} }
@@ -190,6 +194,10 @@
height: 1px; height: 1px;
} }
.h-0 {
height: 0;
}
.h-3\.5 { .h-3\.5 {
height: 0.875rem; height: 0.875rem;
} }