Skip to content

Commit cc2bc1e

Browse files
authored
feat: replace accordion in change editor menu with regular menu (#871)
1 parent cb013db commit cc2bc1e

File tree

10 files changed

+425
-484
lines changed

10 files changed

+425
-484
lines changed

app/assets/javascripts/components/AccountMenu/GeneralAccountMenu.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ export const GeneralAccountMenu: FunctionComponent<Props> = observer(
107107
</>
108108
)}
109109
<div className="h-1px my-2 bg-border"></div>
110-
<Menu a11yLabel="General account menu" closeMenu={closeMenu}>
110+
<Menu
111+
isOpen={appState.accountMenu.show}
112+
a11yLabel="General account menu"
113+
closeMenu={closeMenu}
114+
>
111115
{user ? (
112116
<MenuItem
113117
type={MenuItemType.IconButton}

app/assets/javascripts/components/NotesListOptionsMenu.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ type Props = {
1111
application: WebApplication;
1212
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void;
1313
closeDisplayOptionsMenu: () => void;
14+
isOpen: boolean;
1415
};
1516

1617
export const NotesListOptionsMenu: FunctionComponent<Props> = observer(
17-
({ closeDisplayOptionsMenu, closeOnBlur, application }) => {
18+
({ closeDisplayOptionsMenu, closeOnBlur, application, isOpen }) => {
1819
const menuClassName =
1920
'sn-dropdown sn-dropdown--animated min-w-70 overflow-y-auto \
2021
border-1 border-solid border-main text-sm z-index-dropdown-menu \
@@ -120,7 +121,11 @@ flex flex-col py-2 top-full bottom-0 left-2 absolute';
120121

121122
return (
122123
<div ref={menuRef} className={menuClassName}>
123-
<Menu a11yLabel="Sort by" closeMenu={closeDisplayOptionsMenu}>
124+
<Menu
125+
a11yLabel="Notes list options menu"
126+
closeMenu={closeDisplayOptionsMenu}
127+
isOpen={isOpen}
128+
>
124129
<div className="px-3 my-1 text-xs font-semibold color-text uppercase">
125130
Sort by
126131
</div>

app/assets/javascripts/components/NotesOptions/ChangeEditorOption.tsx

Lines changed: 33 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
import { KeyboardKey } from '@/services/ioService';
2-
import { STRING_EDIT_LOCKED_ATTEMPT } from '@/strings';
32
import { WebApplication } from '@/ui_models/application';
43
import { AppState } from '@/ui_models/app_state';
54
import {
65
MENU_MARGIN_FROM_APP_BORDER,
76
MAX_MENU_SIZE_MULTIPLIER,
87
} from '@/views/constants';
9-
import {
10-
reloadFont,
11-
transactionForAssociateComponentWithCurrentNote,
12-
transactionForDisassociateComponentWithCurrentNote,
13-
} from '@/components/NoteView/NoteView';
148
import {
159
Disclosure,
1610
DisclosureButton,
@@ -19,18 +13,14 @@ import {
1913
import {
2014
ComponentArea,
2115
IconType,
22-
ItemMutator,
23-
NoteMutator,
24-
PrefKey,
2516
SNComponent,
2617
SNNote,
27-
TransactionalMutation,
2818
} from '@standardnotes/snjs';
2919
import { FunctionComponent } from 'preact';
3020
import { useEffect, useRef, useState } from 'preact/hooks';
3121
import { Icon } from '../Icon';
3222
import { createEditorMenuGroups } from './changeEditor/createEditorMenuGroups';
33-
import { EditorAccordionMenu } from './changeEditor/EditorAccordionMenu';
23+
import { ChangeEditorMenu } from './changeEditor/ChangeEditorMenu';
3424

3525
type ChangeEditorOptionProps = {
3626
appState: AppState;
@@ -59,6 +49,7 @@ type MenuPositionStyle = {
5949
right?: number | 'auto';
6050
bottom: number | 'auto';
6151
left?: number | 'auto';
52+
visibility?: 'hidden' | 'visible';
6253
};
6354

6455
const calculateMenuPosition = (
@@ -102,11 +93,13 @@ const calculateMenuPosition = (
10293
position = {
10394
bottom: positionBottom,
10495
right: clientWidth - buttonRect.left,
96+
visibility: 'hidden',
10597
};
10698
} else {
10799
position = {
108100
bottom: positionBottom,
109101
left: buttonRect.right,
102+
visibility: 'hidden',
110103
};
111104
}
112105
}
@@ -121,12 +114,14 @@ const calculateMenuPosition = (
121114
...position,
122115
top: MENU_MARGIN_FROM_APP_BORDER + buttonRect.top - buttonRect.height,
123116
bottom: 'auto',
117+
visibility: 'visible',
124118
};
125119
} else {
126120
return {
127121
...position,
128122
top: MENU_MARGIN_FROM_APP_BORDER,
129123
bottom: 'auto',
124+
visibility: 'visible',
130125
};
131126
}
132127
}
@@ -135,15 +130,16 @@ const calculateMenuPosition = (
135130
return position;
136131
};
137132

138-
const TIME_IN_MS_TO_WAIT_BEFORE_REPAINT = 1;
139-
140133
export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
141134
application,
142-
appState,
143135
closeOnBlur,
144136
note,
145137
}) => {
146138
const [changeEditorMenuOpen, setChangeEditorMenuOpen] = useState(false);
139+
const [changeEditorMenuVisible, setChangeEditorMenuVisible] = useState(false);
140+
const [changeEditorMenuMaxHeight, setChangeEditorMenuMaxHeight] = useState<
141+
number | 'auto'
142+
>('auto');
147143
const [changeEditorMenuPosition, setChangeEditorMenuPosition] =
148144
useState<MenuPositionStyle>({
149145
right: 0,
@@ -193,84 +189,29 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
193189
);
194190

195191
if (newMenuPosition) {
192+
const { clientHeight } = document.documentElement;
193+
const footerElementRect = document
194+
.getElementById('footer-bar')
195+
?.getBoundingClientRect();
196+
const footerHeightInPx = footerElementRect?.height;
197+
198+
if (
199+
footerHeightInPx &&
200+
newMenuPosition.top &&
201+
newMenuPosition.top !== 'auto'
202+
) {
203+
setChangeEditorMenuMaxHeight(
204+
clientHeight - newMenuPosition.top - footerHeightInPx - 2
205+
);
206+
}
207+
196208
setChangeEditorMenuPosition(newMenuPosition);
209+
setChangeEditorMenuVisible(true);
197210
}
198-
}, TIME_IN_MS_TO_WAIT_BEFORE_REPAINT);
211+
});
199212
}
200213
}, [changeEditorMenuOpen]);
201214

202-
const selectComponent = async (component: SNComponent | null) => {
203-
if (component) {
204-
if (component.conflictOf) {
205-
application.changeAndSaveItem(component.uuid, (mutator) => {
206-
mutator.conflictOf = undefined;
207-
});
208-
}
209-
}
210-
211-
const transactions: TransactionalMutation[] = [];
212-
213-
if (appState.getActiveNoteController()?.isTemplateNote) {
214-
await appState.getActiveNoteController().insertTemplatedNote();
215-
}
216-
217-
if (note.locked) {
218-
application.alertService.alert(STRING_EDIT_LOCKED_ATTEMPT);
219-
return;
220-
}
221-
222-
if (!component) {
223-
if (!note.prefersPlainEditor) {
224-
transactions.push({
225-
itemUuid: note.uuid,
226-
mutate: (m: ItemMutator) => {
227-
const noteMutator = m as NoteMutator;
228-
noteMutator.prefersPlainEditor = true;
229-
},
230-
});
231-
}
232-
const currentEditor = application.componentManager.editorForNote(note);
233-
if (currentEditor?.isExplicitlyEnabledForItem(note.uuid)) {
234-
transactions.push(
235-
transactionForDisassociateComponentWithCurrentNote(
236-
currentEditor,
237-
note
238-
)
239-
);
240-
}
241-
reloadFont(application.getPreference(PrefKey.EditorMonospaceEnabled));
242-
} else if (component.area === ComponentArea.Editor) {
243-
const currentEditor = application.componentManager.editorForNote(note);
244-
if (currentEditor && component.uuid !== currentEditor.uuid) {
245-
transactions.push(
246-
transactionForDisassociateComponentWithCurrentNote(
247-
currentEditor,
248-
note
249-
)
250-
);
251-
}
252-
const prefersPlain = note.prefersPlainEditor;
253-
if (prefersPlain) {
254-
transactions.push({
255-
itemUuid: note.uuid,
256-
mutate: (m: ItemMutator) => {
257-
const noteMutator = m as NoteMutator;
258-
noteMutator.prefersPlainEditor = false;
259-
},
260-
});
261-
}
262-
transactions.push(
263-
transactionForAssociateComponentWithCurrentNote(component, note)
264-
);
265-
}
266-
267-
await application.runTransactionalMutations(transactions);
268-
/** Dirtying can happen above */
269-
application.sync();
270-
271-
setSelectedEditor(application.componentManager.editorForNote(note));
272-
};
273-
274215
return (
275216
<Disclosure open={changeEditorMenuOpen} onChange={toggleChangeEditorMenu}>
276217
<DisclosureButton
@@ -299,17 +240,19 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
299240
}}
300241
style={{
301242
...changeEditorMenuPosition,
243+
maxHeight: changeEditorMenuMaxHeight,
302244
position: 'fixed',
303245
}}
304246
className="sn-dropdown flex flex-col max-h-120 min-w-68 fixed overflow-y-auto"
305247
>
306-
<EditorAccordionMenu
248+
<ChangeEditorMenu
307249
application={application}
308250
closeOnBlur={closeOnBlur}
309251
currentEditor={selectedEditor}
252+
setSelectedEditor={setSelectedEditor}
253+
note={note}
310254
groups={editorMenuGroups}
311-
isOpen={changeEditorMenuOpen}
312-
selectComponent={selectComponent}
255+
isOpen={changeEditorMenuVisible}
313256
/>
314257
</DisclosurePanel>
315258
</Disclosure>

0 commit comments

Comments
 (0)