fix: fix tags container width

This commit is contained in:
Antonella Sgarlatta
2021-05-31 16:27:17 -03:00
parent 70e4425e20
commit b54de00b40
4 changed files with 73 additions and 50 deletions

View File

@@ -12,20 +12,23 @@ type Props = {
appState: AppState; appState: AppState;
}; };
const TAGS_ROW_RIGHT_MARGIN = 92;
const TAGS_ROW_HEIGHT = 36; const TAGS_ROW_HEIGHT = 36;
const MIN_OVERFLOW_TOP = 76; const MIN_OVERFLOW_TOP = 76;
const TAGS_RIGHT_MARGIN = 8; const TAG_RIGHT_MARGIN = 8;
const NoteTags = observer(({ application, appState }: Props) => { const NoteTags = observer(({ application, appState }: Props) => {
const { tags, tagsContainerPosition, tagsContainerMaxWidth } = const {
appState.activeNote; overflowedTagsCount,
tags,
tagsContainerPosition,
tagsContainerMaxWidth,
tagsContainerCollapsed,
tagsOverflowed,
} = appState.activeNote;
const [tagsContainerCollapsed, setTagsContainerCollapsed] = useState(true);
const [tagsContainerHeight, setTagsContainerHeight] = const [tagsContainerHeight, setTagsContainerHeight] =
useState(TAGS_ROW_HEIGHT); useState(TAGS_ROW_HEIGHT);
const [overflowCountPosition, setOverflowCountPosition] = useState(0); const [overflowCountPosition, setOverflowCountPosition] = useState(0);
const [overflowCount, setOverflowCount] = useState(0);
const tagsContainerRef = useRef<HTMLDivElement>(); const tagsContainerRef = useRef<HTMLDivElement>();
const tagsRef = useRef<HTMLButtonElement[]>([]); const tagsRef = useRef<HTMLButtonElement[]>([]);
@@ -39,7 +42,7 @@ const NoteTags = observer(({ application, appState }: Props) => {
}; };
const expandTags = () => { const expandTags = () => {
setTagsContainerCollapsed(false); appState.activeNote.setTagsContainerCollapsed(false);
}; };
const isTagOverflowed = useCallback( const isTagOverflowed = useCallback(
@@ -65,7 +68,7 @@ const NoteTags = observer(({ application, appState }: Props) => {
const previousTagRect = const previousTagRect =
tagsRef.current[firstOverflowedTagIndex - 1].getBoundingClientRect(); tagsRef.current[firstOverflowedTagIndex - 1].getBoundingClientRect();
const position = const position =
previousTagRect.right - (tagsContainerPosition ?? 0) + TAGS_RIGHT_MARGIN; previousTagRect.right - (tagsContainerPosition ?? 0) + TAG_RIGHT_MARGIN;
setOverflowCountPosition(position); setOverflowCountPosition(position);
}, [isTagOverflowed, tagsContainerCollapsed, tagsContainerPosition]); }, [isTagOverflowed, tagsContainerCollapsed, tagsContainerPosition]);
@@ -80,8 +83,8 @@ const NoteTags = observer(({ application, appState }: Props) => {
const count = tagsRef.current.filter((tagElement) => const count = tagsRef.current.filter((tagElement) =>
isTagOverflowed(tagElement) isTagOverflowed(tagElement)
).length; ).length;
setOverflowCount(count); appState.activeNote.setOverflowedTagsCount(count);
}, [isTagOverflowed]); }, [appState.activeNote, isTagOverflowed]);
useEffect(() => { useEffect(() => {
appState.activeNote.reloadTagsContainerLayout(); appState.activeNote.reloadTagsContainerLayout();
@@ -97,9 +100,7 @@ const NoteTags = observer(({ application, appState }: Props) => {
]); ]);
const tagClass = `bg-contrast border-0 rounded text-xs color-text py-1 pr-2 flex items-center 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`; mt-2 cursor-pointer hover:bg-secondary-contrast focus:bg-secondary-contrast`;
const overflowedTags = tagsContainerCollapsed && overflowCount > 0;
return ( return (
<div className="flex" style={{ height: tagsContainerHeight }}> <div className="flex" style={{ height: tagsContainerHeight }}>
@@ -111,12 +112,11 @@ const NoteTags = observer(({ application, appState }: Props) => {
style={{ style={{
maxWidth: tagsContainerMaxWidth, maxWidth: tagsContainerMaxWidth,
height: TAGS_ROW_HEIGHT, height: TAGS_ROW_HEIGHT,
marginRight: TAGS_ROW_RIGHT_MARGIN,
}} }}
> >
{tags.map((tag: SNTag, index: number) => ( {tags.map((tag: SNTag, index: number) => (
<button <button
className={`${tagClass} pl-1`} className={`${tagClass} pl-1 mr-2`}
style={{ maxWidth: tagsContainerMaxWidth }} style={{ maxWidth: tagsContainerMaxWidth }}
ref={(element) => { ref={(element) => {
if (element) { if (element) {
@@ -143,17 +143,17 @@ const NoteTags = observer(({ application, appState }: Props) => {
application={application} application={application}
appState={appState} appState={appState}
tagsRef={tagsRef} tagsRef={tagsRef}
tabIndex={overflowedTags ? -1 : 0} tabIndex={tagsOverflowed ? -1 : 0}
/> />
</div> </div>
{overflowCount > 1 && tagsContainerCollapsed && ( {overflowedTagsCount > 1 && tagsContainerCollapsed && (
<button <button
type="button" type="button"
className={`${tagClass} pl-2 absolute`} className={`${tagClass} pl-2 absolute`}
style={{ left: overflowCountPosition }} style={{ left: overflowCountPosition }}
onClick={expandTags} onClick={expandTags}
> >
+{overflowCount} +{overflowedTagsCount}
</button> </button>
)} )}
</div> </div>

View File

@@ -54,7 +54,7 @@ export const NotesOptionsPanel = observer(({ appState }: Props) => {
}} }}
onBlur={closeOnBlur} onBlur={closeOnBlur}
ref={buttonRef} ref={buttonRef}
className="sn-icon-button mt-2" className="sn-icon-button"
> >
<VisuallyHidden>Actions</VisuallyHidden> <VisuallyHidden>Actions</VisuallyHidden>
<Icon type="more" className="block" /> <Icon type="more" className="block" />

View File

@@ -5,6 +5,7 @@ import {
} from '@standardnotes/snjs'; } from '@standardnotes/snjs';
import { import {
action, action,
computed,
makeObservable, makeObservable,
observable, observable,
} from 'mobx'; } from 'mobx';
@@ -15,6 +16,8 @@ export class ActiveNoteState {
tags: SNTag[] = []; tags: SNTag[] = [];
tagsContainerPosition? = 0; tagsContainerPosition? = 0;
tagsContainerMaxWidth: number | 'auto' = 'auto'; tagsContainerMaxWidth: number | 'auto' = 'auto';
tagsContainerCollapsed = true;
overflowedTagsCount = 0;
constructor( constructor(
private application: WebApplication, private application: WebApplication,
@@ -25,9 +28,15 @@ export class ActiveNoteState {
tags: observable, tags: observable,
tagsContainerPosition: observable, tagsContainerPosition: observable,
tagsContainerMaxWidth: observable, tagsContainerMaxWidth: observable,
tagsContainerCollapsed: observable,
overflowedTagsCount: observable,
tagsOverflowed: computed,
setTagsContainerPosition: action, setTagsContainerPosition: action,
setTagsContainerMaxWidth: action, setTagsContainerMaxWidth: action,
setTagsContainerCollapsed: action,
setOverflowedTagsCount: action,
reloadTags: action, reloadTags: action,
}); });
@@ -49,6 +58,10 @@ export class ActiveNoteState {
return this.appState.notes.activeEditor?.note; return this.appState.notes.activeEditor?.note;
} }
get tagsOverflowed(): boolean {
return this.overflowedTagsCount > 0 && this.tagsContainerCollapsed;
}
setTagsContainerPosition(position: number): void { setTagsContainerPosition(position: number): void {
this.tagsContainerPosition = position; this.tagsContainerPosition = position;
} }
@@ -57,6 +70,14 @@ export class ActiveNoteState {
this.tagsContainerMaxWidth = width; this.tagsContainerMaxWidth = width;
} }
setTagsContainerCollapsed(collapsed: boolean): void {
this.tagsContainerCollapsed = collapsed;
}
setOverflowedTagsCount(count: number): void {
this.overflowedTagsCount = count;
}
reloadTags(): void { reloadTags(): void {
const { activeNote } = this; const { activeNote } = this;
if (activeNote) { if (activeNote) {
@@ -65,14 +86,15 @@ export class ActiveNoteState {
} }
reloadTagsContainerLayout(): void { reloadTagsContainerLayout(): void {
const editorElementId = 'editor-column'; const MARGIN = this.tagsContainerCollapsed ? 68 : 24;
const EDITOR_ELEMENT_ID = 'editor-column';
const { clientWidth } = document.documentElement; const { clientWidth } = document.documentElement;
const editorPosition = const editorPosition =
document.getElementById(editorElementId)?.getBoundingClientRect() document.getElementById(EDITOR_ELEMENT_ID)?.getBoundingClientRect()
.left ?? 0; .left ?? 0;
this.appState.activeNote.setTagsContainerPosition(editorPosition); this.appState.activeNote.setTagsContainerPosition(editorPosition);
this.appState.activeNote.setTagsContainerMaxWidth( this.appState.activeNote.setTagsContainerMaxWidth(
clientWidth - editorPosition clientWidth - editorPosition - MARGIN
); );
} }

View File

@@ -24,37 +24,38 @@
ng-if="self.showLockedIcon" ng-if="self.showLockedIcon"
) )
| {{self.lockText}} | {{self.lockText}}
#editor-title-bar.section-title-bar.flex.items-start.justify-between.w-full( #editor-title-bar.section-title-bar.w-full(
ng-show='self.note && !self.note.errorDecrypting' ng-show='self.note && !self.note.errorDecrypting'
) )
div.flex-grow( div.flex.items-start.justify-between
ng-class="{'locked' : self.noteLocked}" div.flex-grow(
ng-class="{'locked' : self.noteLocked}"
)
.title.overflow-auto
input#note-title-editor.input(
ng-blur='self.onTitleBlur()',
ng-change='self.onTitleChange()',
ng-disabled='self.noteLocked',
ng-focus='self.onTitleFocus()',
ng-keyup='$event.keyCode == 13 && self.onTitleEnter($event)',
ng-model='self.editorValues.title',
select-on-focus='true',
spellcheck='false'
)
div.flex.items-center
#save-status
.message(
ng-class="{'warning sk-bold': self.state.syncTakingTooLong, 'danger sk-bold': self.state.saveError}"
) {{self.state.noteStatus.message}}
.desc(ng-show='self.state.noteStatus.desc') {{self.state.noteStatus.desc}}
notes-options-panel(
app-state='self.appState',
ng-if='self.appState.notes.selectedNotesCount > 0'
)
note-tags(
application='self.application'
app-state='self.appState'
) )
.title.overflow-auto
input#note-title-editor.input(
ng-blur='self.onTitleBlur()',
ng-change='self.onTitleChange()',
ng-disabled='self.noteLocked',
ng-focus='self.onTitleFocus()',
ng-keyup='$event.keyCode == 13 && self.onTitleEnter($event)',
ng-model='self.editorValues.title',
select-on-focus='true',
spellcheck='false'
)
note-tags(
application='self.application'
app-state='self.appState'
)
div.flex.items-center
#save-status
.message(
ng-class="{'warning sk-bold': self.state.syncTakingTooLong, 'danger sk-bold': self.state.saveError}"
) {{self.state.noteStatus.message}}
.desc(ng-show='self.state.noteStatus.desc') {{self.state.noteStatus.desc}}
notes-options-panel(
app-state='self.appState',
ng-if='self.appState.notes.selectedNotesCount > 0'
)
.sn-component(ng-if='self.note') .sn-component(ng-if='self.note')
#editor-menu-bar.sk-app-bar.no-edges #editor-menu-bar.sk-app-bar.no-edges
.left .left