diff --git a/src/components/Calendar/RNCalendar.ts b/src/components/Calendar/RNCalendar.ts new file mode 100644 index 0000000..ecf4b8f --- /dev/null +++ b/src/components/Calendar/RNCalendar.ts @@ -0,0 +1,114 @@ +import { + Component, + DayOfWeek, + QCalendarWidget, + QCalendarWidgetSignals, + QFont, +} from "@nodegui/nodegui"; +import { + HorizontalHeaderFormat, + SelectionMode, + VerticalHeaderFormat, +} from "@nodegui/nodegui/dist/lib/QtWidgets/QCalendarWidget"; +import { throwUnsupported } from "../../utils/helpers"; +import { RNComponent } from "../config"; +import { setViewProps, ViewProps } from "../View/RNView"; + +export interface CalendarProps extends ViewProps { + /** + * 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) + */ + dateEditAcceptDelay?: number; + /** + * Sets whether the date edit popup is enabled. [QCalendarWidget: setDateEditEnabled](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setdateeditenabled) + */ + dateEditEnabled?: boolean; + /** + * Sets a value identifying the day displayed in the first column. [QCalendarWidget: setFirstDayOfWeek](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setfirstdayofweek) + */ + firstDayOfWeek?: DayOfWeek; + /** + * Sets a font for the action. [QCalendarWidget: setFont](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setfont) + */ + font?: QFont; + /** + * Sets whether the table grid is displayed. [QCalendarWidget: setGridVisible](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setgridvisible) + */ + gridVisible?: boolean; + /** + * Sets the format of the horizontal header. [QCalendarWidget: setHorizontalHeaderFormat](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#sethorizontalheaderformat) + */ + horizontalHeaderFormat?: HorizontalHeaderFormat; + /** + * Sets whether the navigation bar is shown or not. [QCalendarWidget: setNavigationBarVisible](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setnavigationbarvisible) + */ + navigationBarVisible?: boolean; + /** + * Sets the type of selection the user can make in the calendar. [QCalendarWidget: setSelectionMode](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setselectionmode) + */ + selectionMode?: SelectionMode; + /** + * Sets the format of the vertical header. [QCalendarWidget: setVerticalHeaderFormat](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget#setverticalheaderformat) + */ + verticalHeaderFormat?: VerticalHeaderFormat; +} + +const setCalendarProps = ( + widget: RNCalendar, + newProps: CalendarProps, + oldProps: CalendarProps +) => { + const setter: CalendarProps = { + set dateEditAcceptDelay(delay: number) { + widget.setDateEditAcceptDelay(delay); + }, + set dateEditEnabled(enable: boolean) { + widget.setDateEditEnabled(enable); + }, + set firstDayOfWeek(dayOfWeek: DayOfWeek) { + widget.setFirstDayOfWeek(dayOfWeek); + }, + set font(font: QFont) { + widget.setFont(font); + }, + set gridVisible(show: boolean) { + widget.setGridVisible(show); + }, + set horizontalHeaderFormat(format: HorizontalHeaderFormat) { + widget.setHorizontalHeaderFormat(format); + }, + set navigationBarVisible(visible: boolean) { + widget.setNavigationBarVisible(visible); + }, + set selectionMode(mode: SelectionMode) { + widget.setSelectionMode(mode); + }, + set verticalHeaderFormat(format: VerticalHeaderFormat) { + widget.setVerticalHeaderFormat(format); + }, + }; + Object.assign(setter, newProps); + setViewProps(widget, newProps, oldProps); +}; + +/** + * @ignore + */ +export class RNCalendar extends QCalendarWidget implements RNComponent { + setProps(newProps: CalendarProps, oldProps: CalendarProps): void { + setCalendarProps(this, newProps, oldProps); + } + appendInitialChild(child: Component): void { + throwUnsupported(this); + } + appendChild(child: Component): void { + throwUnsupported(this); + } + insertBefore(child: Component, beforeChild: Component): void { + throwUnsupported(this); + } + removeChild(child: Component): void { + throwUnsupported(this); + } + static tagName = "calendar"; +} diff --git a/src/components/Calendar/index.ts b/src/components/Calendar/index.ts new file mode 100644 index 0000000..6897026 --- /dev/null +++ b/src/components/Calendar/index.ts @@ -0,0 +1,91 @@ +import { ComponentConfig, registerComponent, RNComponent } from "../config"; +import { AppContainer } from "../../reconciler"; +import { Fiber } from "react-reconciler"; +import { CalendarProps, RNCalendar } from "./RNCalendar"; + +class CalendarConfig extends ComponentConfig { + tagName = RNCalendar.tagName; + shouldSetTextContent(nextProps: CalendarProps): boolean { + return false; + } + createInstance( + newProps: CalendarProps, + rootInstance?: AppContainer, + context?: any, + workInProgress?: Fiber + ): RNCalendar { + const widget = new RNCalendar(); + widget.setProps(newProps, {}); + return widget; + } + commitMount( + instance: RNCalendar, + newProps: CalendarProps, + internalInstanceHandle: any + ): void { + if (newProps.visible !== false) { + instance.show(); + } + return; + } + commitUpdate( + instance: RNCalendar, + updatePayload: any, + oldProps: CalendarProps, + newProps: CalendarProps, + finishedWork: Fiber + ): void { + instance.setProps(newProps, oldProps); + } +} + +/** + * The Calendar component provides ability to add calendar widgets. It is based on + * [NodeGui's QCalendarWidget](https://docs.nodegui.org/docs/api/generated/classes/qcalendarwidget/). + * @example + * ```typescriptreact + * import { + * DateFormat, + * DayOfWeek, + * NativeElement, + * QCalendarWidgetSignals, + * QDate, + * } from "@nodegui/nodegui"; + * import { + * Calendar, + * Renderer, + * useEventHandler, + * Window, + * } from "@nodegui/react-nodegui"; + * import React from "react"; + * const App = () => { + * const calendarClickHandler = useEventHandler( + * { + * activated: (nativeDate) => { + * const date = new QDate(nativeDate as unknown as NativeElement); + * console.log(`activated: ${date.toString(DateFormat.SystemLocaleDate)}`); + * }, + * clicked: (nativeDate) => { + * const date = new QDate(nativeDate as unknown as NativeElement); + * console.log(`clicked: ${date.toString(DateFormat.SystemLocaleDate)}`); + * }, + * currentPageChanged: (year, month) => { + * console.log(`currentPageChanged: year, month: ${year}, ${month}`); + * }, + * selectionChanged: () => { + * console.log("selectionChanged"); + * }, + * }, + * [] + * ); + * + * return ( + * + * + * + * ); + * } + * Renderer.render(); + * ``` + */ +export const Calendar = registerComponent(new CalendarConfig()); diff --git a/src/index.ts b/src/index.ts index cc196b6..78e18b8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,6 +15,7 @@ export { LineEdit } from "./components/LineEdit"; export { Menu } from "./components/Menu"; export { MenuBar } from "./components/MenuBar"; export { PlainTextEdit } from "./components/PlainTextEdit"; +export { Calendar } from "./components/Calendar"; export { ProgressBar } from "./components/ProgressBar"; export { RadioButton } from "./components/RadioButton"; export { Dial } from "./components/Dial"; @@ -34,7 +35,7 @@ export { Table } from "./components/Table"; export { TableItem } from "./components/TableItem"; export { List } from "./components/List"; export { ListItem } from "./components/ListItem"; -export { ErrorPrompt } from "./components/ErrorPrompt" +export { ErrorPrompt } from "./components/ErrorPrompt"; export { useEventHandler } from "./hooks"; export { Renderer } from "./renderer"; export { hot, appProxy } from "./development/hot-reload";