Skip to content

Commit eb144a1

Browse files
fix(calendar): polish dialog position (#277)
* fix(calendar/dialog): add dark system theme border * fix(calendar): update dialog positioning logic * fix(calendar/dialog): keep y-position within viewport * fix(calendar/dialog): `max-height` at viewport height * feat(calendar/dialog): increase width and margin
1 parent 8c4da71 commit eb144a1

File tree

6 files changed

+58
-27
lines changed

6 files changed

+58
-27
lines changed

components/calendar/dialog/page.module.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
position: relative;
77
display: flex;
88
height: 100%;
9+
max-height: calc(100vh - 48px);
910

1011
.nav {
1112
display: flex;
@@ -81,8 +82,7 @@
8182
padding: 0 24px;
8283
overflow: auto;
8384
height: 100%;
84-
width: 350px;
85-
min-height: 350px;
85+
width: 400px;
8686
}
8787

8888
@mixin header() {

components/calendar/dialog/surface.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,11 @@
4040
:global(html.dark) .wrapper {
4141
border: 1px solid var(--accents-2);
4242
}
43+
44+
:global(html.system) {
45+
@media (prefers-color-scheme: dark) {
46+
.wrapper {
47+
border: 1px solid var(--accents-2);
48+
}
49+
}
50+
}

components/calendar/dialog/surface.tsx

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default function DialogSurface({
3434
offset,
3535
children,
3636
}: DialogSurfaceProps): JSX.Element {
37-
const { editing, setDialog, dragging, setRnd } = useCalendarState();
37+
const { editing, editingLeftPercent, editingWidthPercent, setDialog, dragging, setRnd } = useCalendarState();
3838

3939
const measured = useRef<boolean>(false);
4040
const [visible, setVisible] = useState<boolean>(false);
@@ -57,8 +57,11 @@ export default function DialogSurface({
5757
const [measureRef, bounds] = useMeasure({ polyfill });
5858

5959
const rndPosition = useMemo(
60-
() => getPosition(editing.time.from, rndWidth + RND_MARGIN),
61-
[editing.time.from, rndWidth]
60+
() => {
61+
const { x, y } = getPosition(editing.time.from, rndWidth + RND_MARGIN);
62+
return { y, x: x + editingLeftPercent * rndWidth };
63+
},
64+
[editing.time.from, rndWidth, editingLeftPercent]
6265
);
6366
const rndHeight = useMemo(() => getHeight(editing.time), [editing.time]);
6467

@@ -67,18 +70,10 @@ export default function DialogSurface({
6770
return visible && !dragging ? x : x + 12;
6871
}, [offset.x, dragging, visible, rndPosition.x, bounds.width]);
6972
const onRight = useMemo(() => {
70-
const x = offset.x + rndPosition.x + rndWidth + PREVIEW_MARGIN;
73+
const x = offset.x + rndPosition.x + rndWidth * editingWidthPercent + PREVIEW_MARGIN;
7174
return visible && !dragging ? x : x - 12;
72-
}, [offset.x, dragging, visible, rndPosition.x, rndWidth]);
73-
74-
const alignedTop = useMemo(() => offset.y + rndPosition.y, [
75-
offset.y,
76-
rndPosition.y,
77-
]);
78-
const alignedBottom = useMemo(
79-
() => offset.y + rndPosition.y - bounds.height + rndHeight,
80-
[offset.y, rndPosition.y, bounds.height, rndHeight]
81-
);
75+
}, [offset.x, dragging, visible, rndPosition.x, rndWidth, editingWidthPercent]);
76+
8277
const alignedCenter = useMemo(
8378
() => offset.y + rndPosition.y - 0.5 * (bounds.height - rndHeight),
8479
[offset.y, rndPosition.y, bounds.height, rndHeight]
@@ -89,14 +84,14 @@ export default function DialogSurface({
8984
document.documentElement.clientHeight || 0,
9085
window.innerHeight || 0
9186
);
92-
if (alignedCenter < 0) return alignedTop;
93-
if (alignedCenter + bounds.height > vh) return alignedBottom;
87+
if (alignedCenter < 24) return 24;
88+
if (alignedCenter + bounds.height + 24 > vh) return vh - bounds.height - 24;
9489
return alignedCenter;
95-
}, [alignedTop, alignedCenter, alignedBottom, bounds.height]);
90+
}, [alignedCenter, bounds.height]);
9691

9792
const props = useSpring({
9893
onRest: () => (!visible && measured.current ? setDialog(false) : undefined),
99-
left: rndPosition.x < rndWidth * 3 ? onRight : onLeft,
94+
left: onRight + bounds.width < window.innerWidth ? onRight : onLeft,
10095
config: { tension: 250, velocity: 50 },
10196
immediate: !measured.current || dragging,
10297
top,

components/calendar/index.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ export default function Calendar({
202202
// the body scrollbar disappear, moving the `fixed` position values).
203203
const [offset, setOffset] = useState<Position>({ x: 0, y: 0 });
204204
const [width, setWidth] = useState<number>(0);
205+
const [editingLeftPercent, setEditingLeftPercent] = useState<number>(0);
206+
const [editingWidthPercent, setEditingWidthPercent] = useState<number>(0);
205207

206208
const onEditStop = useCallback(
207209
(evt?: FormEvent) => {
@@ -222,6 +224,10 @@ export default function Calendar({
222224
editing,
223225
setEditing,
224226
onEditStop,
227+
editingLeftPercent,
228+
setEditingLeftPercent,
229+
editingWidthPercent,
230+
setEditingWidthPercent,
225231
rnd,
226232
setRnd,
227233
dialog,
@@ -235,6 +241,10 @@ export default function Calendar({
235241
editing,
236242
setEditing,
237243
onEditStop,
244+
editingLeftPercent,
245+
setEditingLeftPercent,
246+
editingWidthPercent,
247+
setEditingWidthPercent,
238248
rnd,
239249
setRnd,
240250
dialog,

components/calendar/meetings/item.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export default function MeetingItem({
5555
const {
5656
editing,
5757
setEditing,
58+
setEditingLeftPercent,
59+
setEditingWidthPercent,
5860
rnd,
5961
setRnd,
6062
dialog,
@@ -90,6 +92,8 @@ export default function MeetingItem({
9092
if (mouseMovement > 10) {
9193
removeListeners();
9294
setEditing(meeting);
95+
setEditingLeftPercent(leftPercent);
96+
setEditingWidthPercent(widthPercent);
9397
setEventTarget('middle');
9498
setEventData({
9599
screenX: e.screenX,
@@ -107,6 +111,8 @@ export default function MeetingItem({
107111
removeListeners();
108112
setRnd(false);
109113
setEditing(meeting);
114+
setEditingLeftPercent(leftPercent);
115+
setEditingWidthPercent(widthPercent);
110116
setDialogPage(DialogPage.Display);
111117
setDialog(true);
112118
};
@@ -126,6 +132,8 @@ export default function MeetingItem({
126132
onMouseDown={(evt) => {
127133
evt.stopPropagation();
128134
setEditing(meeting);
135+
setEditingLeftPercent(leftPercent);
136+
setEditingWidthPercent(widthPercent);
129137
setEventTarget('bottom');
130138
setEventData({
131139
screenX: evt.screenX,
@@ -143,6 +151,8 @@ export default function MeetingItem({
143151
onMouseDown={(evt) => {
144152
evt.stopPropagation();
145153
setEditing(meeting);
154+
setEditingLeftPercent(leftPercent);
155+
setEditingWidthPercent(widthPercent);
146156
setEventTarget('top');
147157
setEventData({
148158
screenX: evt.screenX,

components/calendar/state.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { FormEvent, createContext, useContext } from 'react';
22

3-
import { Callback, CallbackParam } from 'lib/model/callback';
3+
import { Callback } from 'lib/model/callback';
44
import { Meeting } from 'lib/model/meeting';
55
import { MeetingsQuery } from 'lib/model/query/meetings';
66

@@ -15,6 +15,10 @@ export interface CalendarState {
1515
editing: Meeting;
1616
setEditing: Callback<Meeting>;
1717
onEditStop: (evt?: FormEvent) => void;
18+
editingLeftPercent: number;
19+
setEditingLeftPercent: Callback<number>;
20+
editingWidthPercent: number;
21+
setEditingWidthPercent: Callback<number>;
1822
rnd: boolean;
1923
setRnd: Callback<boolean>;
2024
dialog: boolean;
@@ -27,15 +31,19 @@ export interface CalendarState {
2731
export const CalendarStateContext = createContext<CalendarState>({
2832
start: new MeetingsQuery().from,
2933
editing: new Meeting(),
30-
setEditing: (param: CallbackParam<Meeting>) => {},
31-
onEditStop: (evt?: FormEvent) => {},
34+
setEditing: () => {},
35+
onEditStop: () => {},
36+
editingLeftPercent: 0,
37+
setEditingLeftPercent: () => {},
38+
editingWidthPercent: 0,
39+
setEditingWidthPercent: () => {},
3240
rnd: false,
33-
setRnd: (param: CallbackParam<boolean>) => {},
41+
setRnd: () => {},
3442
dialog: false,
35-
setDialog: (param: CallbackParam<boolean>) => {},
36-
setDialogPage: (param: CallbackParam<DialogPage>) => {},
43+
setDialog: () => {},
44+
setDialogPage: () => {},
3745
dragging: false,
38-
setDragging: (param: CallbackParam<boolean>) => {},
46+
setDragging: () => {},
3947
});
4048

4149
export const useCalendarState = (): CalendarState =>

0 commit comments

Comments
 (0)