Skip to content

Commit 2e6ac23

Browse files
Add Calendar using QCalendarWidget (#372)
1 parent 730caa3 commit 2e6ac23

File tree

3 files changed

+207
-1
lines changed

3 files changed

+207
-1
lines changed

src/components/Calendar/RNCalendar.ts

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import {
2+
Component,
3+
DayOfWeek,
4+
QCalendarWidget,
5+
QCalendarWidgetSignals,
6+
QFont,
7+
} from "@nodegui/nodegui";
8+
import {
9+
HorizontalHeaderFormat,
10+
SelectionMode,
11+
VerticalHeaderFormat,
12+
} from "@nodegui/nodegui/dist/lib/QtWidgets/QCalendarWidget";
13+
import { throwUnsupported } from "../../utils/helpers";
14+
import { RNComponent } from "../config";
15+
import { setViewProps, ViewProps } from "../View/RNView";
16+
17+
export interface CalendarProps extends ViewProps<QCalendarWidgetSignals> {
18+
/**
19+
* Sets the time an inactive date edit is shown before its contents are accepted. [QCalendarWidget: setDateEditAcceptDelay](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setdateeditacceptdelay)
20+
*/
21+
dateEditAcceptDelay?: number;
22+
/**
23+
* Sets whether the date edit popup is enabled. [QCalendarWidget: setDateEditEnabled](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setdateeditenabled)
24+
*/
25+
dateEditEnabled?: boolean;
26+
/**
27+
* Sets a value identifying the day displayed in the first column. [QCalendarWidget: setFirstDayOfWeek](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setfirstdayofweek)
28+
*/
29+
firstDayOfWeek?: DayOfWeek;
30+
/**
31+
* Sets a font for the action. [QCalendarWidget: setFont](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setfont)
32+
*/
33+
font?: QFont;
34+
/**
35+
* Sets whether the table grid is displayed. [QCalendarWidget: setGridVisible](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setgridvisible)
36+
*/
37+
gridVisible?: boolean;
38+
/**
39+
* Sets the format of the horizontal header. [QCalendarWidget: setHorizontalHeaderFormat](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#sethorizontalheaderformat)
40+
*/
41+
horizontalHeaderFormat?: HorizontalHeaderFormat;
42+
/**
43+
* Sets whether the navigation bar is shown or not. [QCalendarWidget: setNavigationBarVisible](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setnavigationbarvisible)
44+
*/
45+
navigationBarVisible?: boolean;
46+
/**
47+
* Sets the type of selection the user can make in the calendar. [QCalendarWidget: setSelectionMode](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setselectionmode)
48+
*/
49+
selectionMode?: SelectionMode;
50+
/**
51+
* Sets the format of the vertical header. [QCalendarWidget: setVerticalHeaderFormat](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setverticalheaderformat)
52+
*/
53+
verticalHeaderFormat?: VerticalHeaderFormat;
54+
}
55+
56+
const setCalendarProps = (
57+
widget: RNCalendar,
58+
newProps: CalendarProps,
59+
oldProps: CalendarProps
60+
) => {
61+
const setter: CalendarProps = {
62+
set dateEditAcceptDelay(delay: number) {
63+
widget.setDateEditAcceptDelay(delay);
64+
},
65+
set dateEditEnabled(enable: boolean) {
66+
widget.setDateEditEnabled(enable);
67+
},
68+
set firstDayOfWeek(dayOfWeek: DayOfWeek) {
69+
widget.setFirstDayOfWeek(dayOfWeek);
70+
},
71+
set font(font: QFont) {
72+
widget.setFont(font);
73+
},
74+
set gridVisible(show: boolean) {
75+
widget.setGridVisible(show);
76+
},
77+
set horizontalHeaderFormat(format: HorizontalHeaderFormat) {
78+
widget.setHorizontalHeaderFormat(format);
79+
},
80+
set navigationBarVisible(visible: boolean) {
81+
widget.setNavigationBarVisible(visible);
82+
},
83+
set selectionMode(mode: SelectionMode) {
84+
widget.setSelectionMode(mode);
85+
},
86+
set verticalHeaderFormat(format: VerticalHeaderFormat) {
87+
widget.setVerticalHeaderFormat(format);
88+
},
89+
};
90+
Object.assign(setter, newProps);
91+
setViewProps(widget, newProps, oldProps);
92+
};
93+
94+
/**
95+
* @ignore
96+
*/
97+
export class RNCalendar extends QCalendarWidget implements RNComponent {
98+
setProps(newProps: CalendarProps, oldProps: CalendarProps): void {
99+
setCalendarProps(this, newProps, oldProps);
100+
}
101+
appendInitialChild(child: Component): void {
102+
throwUnsupported(this);
103+
}
104+
appendChild(child: Component): void {
105+
throwUnsupported(this);
106+
}
107+
insertBefore(child: Component, beforeChild: Component): void {
108+
throwUnsupported(this);
109+
}
110+
removeChild(child: Component): void {
111+
throwUnsupported(this);
112+
}
113+
static tagName = "calendar";
114+
}

src/components/Calendar/index.ts

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { ComponentConfig, registerComponent, RNComponent } from "../config";
2+
import { AppContainer } from "../../reconciler";
3+
import { Fiber } from "react-reconciler";
4+
import { CalendarProps, RNCalendar } from "./RNCalendar";
5+
6+
class CalendarConfig extends ComponentConfig {
7+
tagName = RNCalendar.tagName;
8+
shouldSetTextContent(nextProps: CalendarProps): boolean {
9+
return false;
10+
}
11+
createInstance(
12+
newProps: CalendarProps,
13+
rootInstance?: AppContainer,
14+
context?: any,
15+
workInProgress?: Fiber
16+
): RNCalendar {
17+
const widget = new RNCalendar();
18+
widget.setProps(newProps, {});
19+
return widget;
20+
}
21+
commitMount(
22+
instance: RNCalendar,
23+
newProps: CalendarProps,
24+
internalInstanceHandle: any
25+
): void {
26+
if (newProps.visible !== false) {
27+
instance.show();
28+
}
29+
return;
30+
}
31+
commitUpdate(
32+
instance: RNCalendar,
33+
updatePayload: any,
34+
oldProps: CalendarProps,
35+
newProps: CalendarProps,
36+
finishedWork: Fiber
37+
): void {
38+
instance.setProps(newProps, oldProps);
39+
}
40+
}
41+
42+
/**
43+
* The Calendar component provides ability to add calendar widgets. It is based on
44+
* [NodeGui's QCalendarWidget](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget/).
45+
* @example
46+
* ```typescriptreact
47+
* import {
48+
* DateFormat,
49+
* DayOfWeek,
50+
* NativeElement,
51+
* QCalendarWidgetSignals,
52+
* QDate,
53+
* } from "@nodegui/nodegui";
54+
* import {
55+
* Calendar,
56+
* Renderer,
57+
* useEventHandler,
58+
* Window,
59+
* } from "@nodegui/react-nodegui";
60+
* import React from "react";
61+
* const App = () => {
62+
* const calendarClickHandler = useEventHandler<QCalendarWidgetSignals>(
63+
* {
64+
* activated: (nativeDate) => {
65+
* const date = new QDate(nativeDate as unknown as NativeElement);
66+
* console.log(`activated: ${date.toString(DateFormat.SystemLocaleDate)}`);
67+
* },
68+
* clicked: (nativeDate) => {
69+
* const date = new QDate(nativeDate as unknown as NativeElement);
70+
* console.log(`clicked: ${date.toString(DateFormat.SystemLocaleDate)}`);
71+
* },
72+
* currentPageChanged: (year, month) => {
73+
* console.log(`currentPageChanged: year, month: ${year}, ${month}`);
74+
* },
75+
* selectionChanged: () => {
76+
* console.log("selectionChanged");
77+
* },
78+
* },
79+
* []
80+
* );
81+
*
82+
* return (
83+
* <Window>
84+
* <Calendar firstDayOfWeek={DayOfWeek.Sunday} on={calendarClickHandler} />
85+
* </Window>
86+
* );
87+
* }
88+
* Renderer.render(<App />);
89+
* ```
90+
*/
91+
export const Calendar = registerComponent<CalendarProps>(new CalendarConfig());

src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export { LineEdit } from "./components/LineEdit";
1515
export { Menu } from "./components/Menu";
1616
export { MenuBar } from "./components/MenuBar";
1717
export { PlainTextEdit } from "./components/PlainTextEdit";
18+
export { Calendar } from "./components/Calendar";
1819
export { ProgressBar } from "./components/ProgressBar";
1920
export { RadioButton } from "./components/RadioButton";
2021
export { Dial } from "./components/Dial";
@@ -34,7 +35,7 @@ export { Table } from "./components/Table";
3435
export { TableItem } from "./components/TableItem";
3536
export { List } from "./components/List";
3637
export { ListItem } from "./components/ListItem";
37-
export { ErrorPrompt } from "./components/ErrorPrompt"
38+
export { ErrorPrompt } from "./components/ErrorPrompt";
3839
export { useEventHandler } from "./hooks";
3940
export { Renderer } from "./renderer";
4041
export { hot, appProxy } from "./development/hot-reload";

0 commit comments

Comments
 (0)