fix: fix tags container width
This commit is contained in:
@@ -12,20 +12,23 @@ type Props = {
|
||||
appState: AppState;
|
||||
};
|
||||
|
||||
const TAGS_ROW_RIGHT_MARGIN = 92;
|
||||
const TAGS_ROW_HEIGHT = 36;
|
||||
const MIN_OVERFLOW_TOP = 76;
|
||||
const TAGS_RIGHT_MARGIN = 8;
|
||||
const TAG_RIGHT_MARGIN = 8;
|
||||
|
||||
const NoteTags = observer(({ application, appState }: Props) => {
|
||||
const { tags, tagsContainerPosition, tagsContainerMaxWidth } =
|
||||
appState.activeNote;
|
||||
const {
|
||||
overflowedTagsCount,
|
||||
tags,
|
||||
tagsContainerPosition,
|
||||
tagsContainerMaxWidth,
|
||||
tagsContainerCollapsed,
|
||||
tagsOverflowed,
|
||||
} = appState.activeNote;
|
||||
|
||||
const [tagsContainerCollapsed, setTagsContainerCollapsed] = useState(true);
|
||||
const [tagsContainerHeight, setTagsContainerHeight] =
|
||||
useState(TAGS_ROW_HEIGHT);
|
||||
const [overflowCountPosition, setOverflowCountPosition] = useState(0);
|
||||
const [overflowCount, setOverflowCount] = useState(0);
|
||||
|
||||
const tagsContainerRef = useRef<HTMLDivElement>();
|
||||
const tagsRef = useRef<HTMLButtonElement[]>([]);
|
||||
@@ -39,7 +42,7 @@ const NoteTags = observer(({ application, appState }: Props) => {
|
||||
};
|
||||
|
||||
const expandTags = () => {
|
||||
setTagsContainerCollapsed(false);
|
||||
appState.activeNote.setTagsContainerCollapsed(false);
|
||||
};
|
||||
|
||||
const isTagOverflowed = useCallback(
|
||||
@@ -65,7 +68,7 @@ const NoteTags = observer(({ application, appState }: Props) => {
|
||||
const previousTagRect =
|
||||
tagsRef.current[firstOverflowedTagIndex - 1].getBoundingClientRect();
|
||||
const position =
|
||||
previousTagRect.right - (tagsContainerPosition ?? 0) + TAGS_RIGHT_MARGIN;
|
||||
previousTagRect.right - (tagsContainerPosition ?? 0) + TAG_RIGHT_MARGIN;
|
||||
setOverflowCountPosition(position);
|
||||
}, [isTagOverflowed, tagsContainerCollapsed, tagsContainerPosition]);
|
||||
|
||||
@@ -80,8 +83,8 @@ const NoteTags = observer(({ application, appState }: Props) => {
|
||||
const count = tagsRef.current.filter((tagElement) =>
|
||||
isTagOverflowed(tagElement)
|
||||
).length;
|
||||
setOverflowCount(count);
|
||||
}, [isTagOverflowed]);
|
||||
appState.activeNote.setOverflowedTagsCount(count);
|
||||
}, [appState.activeNote, isTagOverflowed]);
|
||||
|
||||
useEffect(() => {
|
||||
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
|
||||
mt-2 mr-2 cursor-pointer hover:bg-secondary-contrast focus:bg-secondary-contrast`;
|
||||
|
||||
const overflowedTags = tagsContainerCollapsed && overflowCount > 0;
|
||||
mt-2 cursor-pointer hover:bg-secondary-contrast focus:bg-secondary-contrast`;
|
||||
|
||||
return (
|
||||
<div className="flex" style={{ height: tagsContainerHeight }}>
|
||||
@@ -111,12 +112,11 @@ const NoteTags = observer(({ application, appState }: Props) => {
|
||||
style={{
|
||||
maxWidth: tagsContainerMaxWidth,
|
||||
height: TAGS_ROW_HEIGHT,
|
||||
marginRight: TAGS_ROW_RIGHT_MARGIN,
|
||||
}}
|
||||
>
|
||||
{tags.map((tag: SNTag, index: number) => (
|
||||
<button
|
||||
className={`${tagClass} pl-1`}
|
||||
className={`${tagClass} pl-1 mr-2`}
|
||||
style={{ maxWidth: tagsContainerMaxWidth }}
|
||||
ref={(element) => {
|
||||
if (element) {
|
||||
@@ -143,17 +143,17 @@ const NoteTags = observer(({ application, appState }: Props) => {
|
||||
application={application}
|
||||
appState={appState}
|
||||
tagsRef={tagsRef}
|
||||
tabIndex={overflowedTags ? -1 : 0}
|
||||
tabIndex={tagsOverflowed ? -1 : 0}
|
||||
/>
|
||||
</div>
|
||||
{overflowCount > 1 && tagsContainerCollapsed && (
|
||||
{overflowedTagsCount > 1 && tagsContainerCollapsed && (
|
||||
<button
|
||||
type="button"
|
||||
className={`${tagClass} pl-2 absolute`}
|
||||
style={{ left: overflowCountPosition }}
|
||||
onClick={expandTags}
|
||||
>
|
||||
+{overflowCount}
|
||||
+{overflowedTagsCount}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -54,7 +54,7 @@ export const NotesOptionsPanel = observer(({ appState }: Props) => {
|
||||
}}
|
||||
onBlur={closeOnBlur}
|
||||
ref={buttonRef}
|
||||
className="sn-icon-button mt-2"
|
||||
className="sn-icon-button"
|
||||
>
|
||||
<VisuallyHidden>Actions</VisuallyHidden>
|
||||
<Icon type="more" className="block" />
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
} from '@standardnotes/snjs';
|
||||
import {
|
||||
action,
|
||||
computed,
|
||||
makeObservable,
|
||||
observable,
|
||||
} from 'mobx';
|
||||
@@ -15,6 +16,8 @@ export class ActiveNoteState {
|
||||
tags: SNTag[] = [];
|
||||
tagsContainerPosition? = 0;
|
||||
tagsContainerMaxWidth: number | 'auto' = 'auto';
|
||||
tagsContainerCollapsed = true;
|
||||
overflowedTagsCount = 0;
|
||||
|
||||
constructor(
|
||||
private application: WebApplication,
|
||||
@@ -25,9 +28,15 @@ export class ActiveNoteState {
|
||||
tags: observable,
|
||||
tagsContainerPosition: observable,
|
||||
tagsContainerMaxWidth: observable,
|
||||
tagsContainerCollapsed: observable,
|
||||
overflowedTagsCount: observable,
|
||||
|
||||
tagsOverflowed: computed,
|
||||
|
||||
setTagsContainerPosition: action,
|
||||
setTagsContainerMaxWidth: action,
|
||||
setTagsContainerCollapsed: action,
|
||||
setOverflowedTagsCount: action,
|
||||
reloadTags: action,
|
||||
});
|
||||
|
||||
@@ -49,6 +58,10 @@ export class ActiveNoteState {
|
||||
return this.appState.notes.activeEditor?.note;
|
||||
}
|
||||
|
||||
get tagsOverflowed(): boolean {
|
||||
return this.overflowedTagsCount > 0 && this.tagsContainerCollapsed;
|
||||
}
|
||||
|
||||
setTagsContainerPosition(position: number): void {
|
||||
this.tagsContainerPosition = position;
|
||||
}
|
||||
@@ -57,6 +70,14 @@ export class ActiveNoteState {
|
||||
this.tagsContainerMaxWidth = width;
|
||||
}
|
||||
|
||||
setTagsContainerCollapsed(collapsed: boolean): void {
|
||||
this.tagsContainerCollapsed = collapsed;
|
||||
}
|
||||
|
||||
setOverflowedTagsCount(count: number): void {
|
||||
this.overflowedTagsCount = count;
|
||||
}
|
||||
|
||||
reloadTags(): void {
|
||||
const { activeNote } = this;
|
||||
if (activeNote) {
|
||||
@@ -65,14 +86,15 @@ export class ActiveNoteState {
|
||||
}
|
||||
|
||||
reloadTagsContainerLayout(): void {
|
||||
const editorElementId = 'editor-column';
|
||||
const MARGIN = this.tagsContainerCollapsed ? 68 : 24;
|
||||
const EDITOR_ELEMENT_ID = 'editor-column';
|
||||
const { clientWidth } = document.documentElement;
|
||||
const editorPosition =
|
||||
document.getElementById(editorElementId)?.getBoundingClientRect()
|
||||
document.getElementById(EDITOR_ELEMENT_ID)?.getBoundingClientRect()
|
||||
.left ?? 0;
|
||||
this.appState.activeNote.setTagsContainerPosition(editorPosition);
|
||||
this.appState.activeNote.setTagsContainerMaxWidth(
|
||||
clientWidth - editorPosition
|
||||
clientWidth - editorPosition - MARGIN
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,37 +24,38 @@
|
||||
ng-if="self.showLockedIcon"
|
||||
)
|
||||
| {{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'
|
||||
)
|
||||
div.flex-grow(
|
||||
ng-class="{'locked' : self.noteLocked}"
|
||||
div.flex.items-start.justify-between
|
||||
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')
|
||||
#editor-menu-bar.sk-app-bar.no-edges
|
||||
.left
|
||||
|
||||
Reference in New Issue
Block a user