Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 15 additions & 38 deletions app/assets/javascripts/components/ChangeEditorButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ import {
DisclosurePanel,
} from '@reach/disclosure';
import VisuallyHidden from '@reach/visually-hidden';
import { ComponentArea, SNComponent } from '@standardnotes/snjs';
import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import { useEffect, useRef, useState } from 'preact/hooks';
import { useRef, useState } from 'preact/hooks';
import { Icon } from './Icon';
import { ChangeEditorMenu } from './NotesOptions/changeEditor/ChangeEditorMenu';
import { createEditorMenuGroups } from './NotesOptions/changeEditor/createEditorMenuGroups';
import { EditorMenuGroup } from './NotesOptions/ChangeEditorOption';
import { useCloseOnBlur } from './utils';

type Props = {
Expand All @@ -26,7 +23,8 @@ type Props = {
export const ChangeEditorButton: FunctionComponent<Props> = observer(
({ application, appState, onClickPreprocessing }) => {
const note = Object.values(appState.notes.selectedNotes)[0];
const [open, setOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [isVisible, setIsVisible] = useState(false);
const [position, setPosition] = useState({
top: 0,
right: 0,
Expand All @@ -35,28 +33,7 @@ export const ChangeEditorButton: FunctionComponent<Props> = observer(
const buttonRef = useRef<HTMLButtonElement>(null);
const panelRef = useRef<HTMLDivElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const [closeOnBlur] = useCloseOnBlur(containerRef, setOpen);
const [editors] = useState<SNComponent[]>(() =>
application.componentManager
.componentsForArea(ComponentArea.Editor)
.sort((a, b) => {
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
})
);
const [editorMenuGroups, setEditorMenuGroups] = useState<EditorMenuGroup[]>(
[]
);
const [currentEditor, setCurrentEditor] = useState<SNComponent>();

useEffect(() => {
setEditorMenuGroups(createEditorMenuGroups(application, editors));
}, [application, editors]);

useEffect(() => {
if (note) {
setCurrentEditor(application.componentManager.editorForNote(note));
}
}, [application, note]);
const [closeOnBlur] = useCloseOnBlur(containerRef, setIsOpen);

const toggleChangeEditorMenu = async () => {
const rect = buttonRef.current?.getBoundingClientRect();
Expand All @@ -81,22 +58,25 @@ export const ChangeEditorButton: FunctionComponent<Props> = observer(
right: document.body.clientWidth - rect.right,
});

const newOpenState = !open;
const newOpenState = !isOpen;
if (newOpenState && onClickPreprocessing) {
await onClickPreprocessing();
}

setOpen(newOpenState);
setIsOpen(newOpenState);
setTimeout(() => {
setIsVisible(newOpenState);
});
}
};

return (
<div ref={containerRef}>
<Disclosure open={open} onChange={toggleChangeEditorMenu}>
<Disclosure open={isOpen} onChange={toggleChangeEditorMenu}>
<DisclosureButton
onKeyDown={(event) => {
if (event.key === 'Escape') {
setOpen(false);
setIsOpen(false);
}
}}
onBlur={closeOnBlur}
Expand All @@ -109,7 +89,7 @@ export const ChangeEditorButton: FunctionComponent<Props> = observer(
<DisclosurePanel
onKeyDown={(event) => {
if (event.key === 'Escape') {
setOpen(false);
setIsOpen(false);
buttonRef.current?.focus();
}
}}
Expand All @@ -121,17 +101,14 @@ export const ChangeEditorButton: FunctionComponent<Props> = observer(
className="sn-dropdown sn-dropdown--animated min-w-68 max-h-120 max-w-xs flex flex-col overflow-y-auto fixed"
onBlur={closeOnBlur}
>
{open && (
{isOpen && (
<ChangeEditorMenu
closeOnBlur={closeOnBlur}
application={application}
isOpen={open}
currentEditor={currentEditor}
setSelectedEditor={setCurrentEditor}
isVisible={isVisible}
note={note}
groups={editorMenuGroups}
closeMenu={() => {
setOpen(false);
setIsOpen(false);
}}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,10 @@ import {
DisclosureButton,
DisclosurePanel,
} from '@reach/disclosure';
import {
ComponentArea,
IconType,
SNComponent,
SNNote,
} from '@standardnotes/snjs';
import { IconType, SNComponent, SNNote } from '@standardnotes/snjs';
import { FunctionComponent } from 'preact';
import { useEffect, useRef, useState } from 'preact/hooks';
import { Icon } from '../Icon';
import { createEditorMenuGroups } from './changeEditor/createEditorMenuGroups';
import { ChangeEditorMenu } from './changeEditor/ChangeEditorMenu';
import {
calculateSubmenuStyle,
Expand Down Expand Up @@ -49,74 +43,53 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
closeOnBlur,
note,
}) => {
const [changeEditorMenuOpen, setChangeEditorMenuOpen] = useState(false);
const [changeEditorMenuVisible, setChangeEditorMenuVisible] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [isVisible, setIsVisible] = useState(false);
const [menuStyle, setMenuStyle] = useState<SubmenuStyle>({
right: 0,
bottom: 0,
maxHeight: 'auto',
});
const changeEditorMenuRef = useRef<HTMLDivElement>(null);
const changeEditorButtonRef = useRef<HTMLButtonElement>(null);
const [editors] = useState<SNComponent[]>(() =>
application.componentManager
.componentsForArea(ComponentArea.Editor)
.sort((a, b) => {
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
})
);
const [editorMenuGroups, setEditorMenuGroups] = useState<EditorMenuGroup[]>(
[]
);
const [selectedEditor, setSelectedEditor] = useState(() =>
application.componentManager.editorForNote(note)
);

useEffect(() => {
setEditorMenuGroups(createEditorMenuGroups(application, editors));
}, [application, editors]);

useEffect(() => {
setSelectedEditor(application.componentManager.editorForNote(note));
}, [application, note]);
const menuRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null);

const toggleChangeEditorMenu = () => {
if (!changeEditorMenuOpen) {
const menuStyle = calculateSubmenuStyle(changeEditorButtonRef.current);
if (!isOpen) {
const menuStyle = calculateSubmenuStyle(buttonRef.current);
if (menuStyle) {
setMenuStyle(menuStyle);
}
}

setChangeEditorMenuOpen(!changeEditorMenuOpen);
setIsOpen(!isOpen);
};

useEffect(() => {
if (changeEditorMenuOpen) {
if (isOpen) {
setTimeout(() => {
const newMenuStyle = calculateSubmenuStyle(
changeEditorButtonRef.current,
changeEditorMenuRef.current
buttonRef.current,
menuRef.current
);

if (newMenuStyle) {
setMenuStyle(newMenuStyle);
setChangeEditorMenuVisible(true);
setIsVisible(true);
}
});
}
}, [changeEditorMenuOpen]);
}, [isOpen]);

return (
<Disclosure open={changeEditorMenuOpen} onChange={toggleChangeEditorMenu}>
<Disclosure open={isOpen} onChange={toggleChangeEditorMenu}>
<DisclosureButton
onKeyDown={(event) => {
if (event.key === KeyboardKey.Escape) {
setChangeEditorMenuOpen(false);
setIsOpen(false);
}
}}
onBlur={closeOnBlur}
ref={changeEditorButtonRef}
ref={buttonRef}
className="sn-dropdown-item justify-between"
>
<div className="flex items-center">
Expand All @@ -126,11 +99,11 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
<Icon type="chevron-right" className="color-neutral" />
</DisclosureButton>
<DisclosurePanel
ref={changeEditorMenuRef}
ref={menuRef}
onKeyDown={(event) => {
if (event.key === KeyboardKey.Escape) {
setChangeEditorMenuOpen(false);
changeEditorButtonRef.current?.focus();
setIsOpen(false);
buttonRef.current?.focus();
}
}}
style={{
Expand All @@ -139,17 +112,14 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
}}
className="sn-dropdown flex flex-col max-h-120 min-w-68 fixed overflow-y-auto"
>
{changeEditorMenuOpen && (
{isOpen && (
<ChangeEditorMenu
application={application}
closeOnBlur={closeOnBlur}
currentEditor={selectedEditor}
setSelectedEditor={setSelectedEditor}
note={note}
groups={editorMenuGroups}
isOpen={changeEditorMenuVisible}
isVisible={isVisible}
closeMenu={() => {
setChangeEditorMenuOpen(false);
setIsOpen(false);
}}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ import {
TransactionalMutation,
} from '@standardnotes/snjs';
import { Fragment, FunctionComponent } from 'preact';
import { StateUpdater, useCallback } from 'preact/hooks';
import { useCallback, useEffect, useState } from 'preact/hooks';
import { EditorMenuItem, EditorMenuGroup } from '../ChangeEditorOption';
import { PLAIN_EDITOR_NAME } from './createEditorMenuGroups';
import {
createEditorMenuGroups,
PLAIN_EDITOR_NAME,
} from './createEditorMenuGroups';

type ChangeEditorMenuProps = {
application: WebApplication;
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void;
closeMenu: () => void;
groups: EditorMenuGroup[];
isOpen: boolean;
currentEditor: SNComponent | undefined;
isVisible: boolean;
note: SNNote;
setSelectedEditor: StateUpdater<SNComponent | undefined>;
};

const getGroupId = (group: EditorMenuGroup) =>
Expand All @@ -41,12 +41,29 @@ export const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
application,
closeOnBlur,
closeMenu,
groups,
isOpen,
currentEditor,
setSelectedEditor,
isVisible,
note,
}) => {
const [editors] = useState<SNComponent[]>(() =>
application.componentManager
.componentsForArea(ComponentArea.Editor)
.sort((a, b) => {
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
})
);
const [groups, setGroups] = useState<EditorMenuGroup[]>([]);
const [currentEditor, setCurrentEditor] = useState<SNComponent>();

useEffect(() => {
setGroups(createEditorMenuGroups(application, editors));
}, [application, editors]);

useEffect(() => {
if (note) {
setCurrentEditor(application.componentManager.editorForNote(note));
}
}, [application, note]);

const premiumModal = usePremiumModal();

const isSelectedEditor = useCallback(
Expand Down Expand Up @@ -138,7 +155,7 @@ export const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
/** Dirtying can happen above */
application.sync();

setSelectedEditor(application.componentManager.editorForNote(note));
setCurrentEditor(application.componentManager.editorForNote(note));
};

const selectEditor = async (itemToBeSelected: EditorMenuItem) => {
Expand Down Expand Up @@ -179,7 +196,7 @@ export const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
<Menu
className="pt-0.5 pb-1"
a11yLabel="Change editor menu"
isOpen={isOpen}
isOpen={isVisible}
>
{groups
.filter((group) => group.items && group.items.length)
Expand Down