chore(react/collections): reintroduce calendar title & type touch bar

This commit is contained in:
Elian Doran
2025-09-06 14:59:57 +03:00
parent 4c20ac0b1c
commit 1917c04baf
4 changed files with 61 additions and 13 deletions

View File

@@ -4,10 +4,9 @@ import { RefObject } from "preact";
interface CalendarProps extends CalendarOptions { interface CalendarProps extends CalendarOptions {
calendarRef?: RefObject<FullCalendar>; calendarRef?: RefObject<FullCalendar>;
tabIndex?: number;
} }
export default function Calendar({ tabIndex, calendarRef, ...options }: CalendarProps) { export default function Calendar({ calendarRef, ...options }: CalendarProps) {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
useLayoutEffect(() => { useLayoutEffect(() => {
@@ -24,6 +23,6 @@ export default function Calendar({ tabIndex, calendarRef, ...options }: Calendar
}, [ containerRef, options ]); }, [ containerRef, options ]);
return ( return (
<div ref={containerRef} className="calendar-container" tabIndex={tabIndex} /> <div ref={containerRef} className="calendar-container" />
); );
} }

View File

@@ -19,6 +19,7 @@ import FNote from "../../../entities/fnote";
import Button, { ButtonGroup } from "../../react/Button"; import Button, { ButtonGroup } from "../../react/Button";
import ActionButton from "../../react/ActionButton"; import ActionButton from "../../react/ActionButton";
import { RefObject } from "preact"; import { RefObject } from "preact";
import TouchBar, { TouchBarLabel, TouchBarSegmentedControl } from "../../react/TouchBar";
interface CalendarViewData { interface CalendarViewData {
@@ -114,13 +115,12 @@ export default function CalendarView({ note, noteIds }: ViewModeProps<CalendarVi
}); });
return (plugins && return (plugins &&
<div className="calendar-view" ref={containerRef}> <div className="calendar-view" ref={containerRef} tabIndex={100}>
<CalendarHeader calendarRef={calendarRef} /> <CalendarHeader calendarRef={calendarRef} />
<Calendar <Calendar
events={eventBuilder} events={eventBuilder}
calendarRef={calendarRef} calendarRef={calendarRef}
plugins={plugins} plugins={plugins}
tabIndex={100}
initialView={initialView.current && SUPPORTED_CALENDAR_VIEW_TYPE.includes(initialView.current) ? initialView.current : "dayGridMonth"} initialView={initialView.current && SUPPORTED_CALENDAR_VIEW_TYPE.includes(initialView.current) ? initialView.current : "dayGridMonth"}
headerToolbar={false} headerToolbar={false}
firstDay={firstDayOfWeek ?? 0} firstDay={firstDayOfWeek ?? 0}
@@ -139,6 +139,7 @@ export default function CalendarView({ note, noteIds }: ViewModeProps<CalendarVi
} }
}} }}
/> />
<CalendarTouchBar calendarRef={calendarRef} />
</div> </div>
); );
} }
@@ -305,8 +306,36 @@ function useEventDisplayCustomization() {
return { eventDidMount }; return { eventDidMount };
} }
function useTouchBarCustomization(api: FullCalendar) { function CalendarTouchBar({ calendarRef }: { calendarRef: RefObject<FullCalendar> }) {
useTouchBar(() => { // Wait for the calendar ref to become available.
const [ ready, setReady ] = useState(false);
useEffect(() => setReady(true), []);
const [ , setTitle ] = useState<string>();
const viewType = calendarRef.current?.view.type;
}, [ api ]); useEffect(() => {
const api = calendarRef.current;
function onDatesSet() {
setTitle(calendarRef.current?.view.title);
}
onDatesSet();
api?.on("datesSet", onDatesSet);
return () => api?.off("datesSet", onDatesSet)
}, [ calendarRef ]);
return ready && (
<TouchBar>
<TouchBarLabel label={calendarRef.current?.view.title ?? ""} />
<TouchBarSegmentedControl
mode="single"
segments={CALENDAR_VIEWS.map(({ name }) => ({
label: name,
}))}
selectedIndex={CALENDAR_VIEWS.findIndex(v => v.type === viewType) ?? 0}
onChange={(selectedIndex) => calendarRef.current?.changeView(CALENDAR_VIEWS[selectedIndex].type)}
/>
</TouchBar>
);
} }

View File

@@ -26,6 +26,15 @@ interface ButtonProps {
enabled?: boolean; enabled?: boolean;
} }
interface SegmentedControlProps {
mode: "single" | "buttons";
segments: {
label: string;
}[];
selectedIndex?: number;
onChange?: (selectedIndex: number, isSelected: boolean) => void;
}
interface TouchBarContextApi { interface TouchBarContextApi {
addItem(item: TouchBarItem): void; addItem(item: TouchBarItem): void;
TouchBar: typeof Electron.TouchBar; TouchBar: typeof Electron.TouchBar;
@@ -72,6 +81,8 @@ export default function TouchBar({ children }: TouchBarProps) {
} }
}); });
console.log("Touch bar state", isFocused, items);
return ( return (
<TouchBarContext.Provider value={api}> <TouchBarContext.Provider value={api}>
{children} {children}
@@ -119,3 +130,17 @@ export function TouchBarButton({ label, click, enabled }: ButtonProps) {
return <></>; return <></>;
} }
export function TouchBarSegmentedControl({ mode, segments, selectedIndex, onChange }: SegmentedControlProps) {
const api = useContext(TouchBarContext);
if (api) {
const item = new api.TouchBar.TouchBarSegmentedControl({
mode, segments, selectedIndex,
change: onChange
});
api.addItem(item);
}
return <></>;
}

View File

@@ -61,11 +61,6 @@ export default class CalendarView extends ViewMode<{}> {
} }
index++; index++;
// Text button.
if (subItem.innerText) {
segments.push({ label: subItem.innerText });
continue;
}
// Icon button. // Icon button.
const iconEl = subItem.querySelector("span.fc-icon"); const iconEl = subItem.querySelector("span.fc-icon");