Skip to content

Reference

Accessible imports for the panel_full_calendar package.

Calendar

Bases: JSComponent

The Calendar widget is a wrapper around the FullCalendar library.

See https://fullcalendar.io/docs for more information on the parameters.

Source code in src/panel_full_calendar/main.py
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
class Calendar(JSComponent):
    """
    The Calendar widget is a wrapper around the FullCalendar library.

    See https://fullcalendar.io/docs for more information on the parameters.
    """

    all_day_maintain_duration = param.Boolean(
        default=False,
        doc="Determines how an event's duration should be mutated when it is dragged from a timed section to an all-day section and vice versa.",
    )

    aspect_ratio = param.Number(default=None, doc="Sets the width-to-height aspect ratio of the calendar.")

    business_hours = param.Dict(default=None, doc="Emphasizes certain time slots on the calendar.")

    button_icons = param.Dict(
        default={},
        doc="Icons that will be displayed in buttons of the header/footer toolbar.",
    )

    button_text = param.Dict(
        default={},
        doc="Text that will be displayed on buttons of the header/footer toolbar.",
    )

    current_date = param.String(
        default=None,
        constant=True,
        doc="The onload or current date of the calendar view. Use go_to_date() to change the date.",
    )

    current_date_callback = param.Callable(
        default=None,
        doc="A callback that will be called when the current date changes.",
    )

    current_view = param.Selector(
        default="dayGridMonth",
        objects=[
            "dayGridMonth",
            "dayGridWeek",
            "dayGridDay",
            "timeGridWeek",
            "timeGridDay",
            "listWeek",
            "listMonth",
            "listYear",
            "multiMonthYear",
        ],
        constant=True,
        doc="The onload or current view of the calendar. Use change_view() to change the view.",
    )

    current_view_callback = param.Callable(
        default=None,
        doc="A callback that will be called when the current view changes.",
    )

    date_alignment = param.String(default=None, doc="Determines how certain views should be initially aligned.")

    date_click_callback = param.Callable(
        default=None,
        doc="A callback that will be called when a date is clicked.",
    )

    date_delta = param.String(
        default=None,
        doc="The duration to move forward/backward when prev/next is clicked.",
    )

    day_max_event_rows = param.Integer(
        default=False,
        doc=(
            "In dayGrid view, the max number of stacked event levels within a given day. "
            "This includes the +more link if present. The rest will show up in a popover."
        ),
    )

    day_max_events = param.Integer(
        default=None,
        doc=("In dayGrid view, the max number of events within a given day, not counting the +more link. " "The rest will show up in a popover."),
    )

    day_popover_format = param.Dict(
        default=None,
        doc="Determines the date format of title of the popover created by the moreLinkClick option.",
    )

    display_event_end = param.Boolean(
        default=None,
        doc="Whether or not to display an event's end time.",
    )

    display_event_time = param.Boolean(
        default=True,
        doc="Whether or not to display the text for an event's date/time.",
    )

    drag_revert_duration = param.Integer(
        default=500,
        doc="Time it takes for an event to revert to its original position after an unsuccessful drag.",
    )

    drag_scroll = param.Boolean(
        default=True,
        doc="Whether to automatically scroll the scroll-containers during event drag-and-drop and date selecting.",
    )

    editable = param.Boolean(
        default=False,
        doc="Determines whether the events on the calendar can be modified.",
    )

    events_in_view = param.List(
        default=[],
        doc="List of events that are currently in view on the calendar.",
        constant=True,
    )

    event_background_color = param.Color(
        default=None,
        doc="Sets the background color for all events on the calendar.",
    )

    event_border_color = param.Color(
        default=None,
        doc="Sets the border color for all events on the calendar.",
    )

    event_change_callback = param.Callable(
        default=None,
        doc="A callback that will be called when an event is changed.",
    )

    event_color = param.Color(
        default=None,
        doc="Sets the background and border colors for all events on the calendar.",
    )

    event_click_callback = param.Callable(
        default=None,
        doc="A callback that will be called when an event is clicked.",
    )

    event_display = param.String(
        default="auto",
        doc="Controls which preset rendering style events use.",
    )

    event_drag_min_distance = param.Integer(
        default=5,
        doc="How many pixels the user's mouse/touch must move before an event drag activates.",
    )

    event_drag_start_callback = param.Callable(
        default=None,
        doc="Triggered when event dragging begins.",
    )

    event_drag_stop_callback = param.Callable(
        default=None,
        doc="Triggered when event dragging stops.",
    )

    event_drop_callback = param.Callable(
        default=None,
        doc="Triggered when dragging stops and the event has moved to a different day/time.",
    )

    event_duration_editable = param.Boolean(
        default=True,
        doc="Allow events' durations to be editable through resizing.",
    )

    event_keys_auto_camel_case = param.Boolean(
        default=True,
        doc=(
            "Whether to automatically convert value and event keys to camelCase for convenience. "
            "However, this can slow down the widget if there are many events or if the events are large."
        ),
    )

    event_keys_auto_snake_case = param.Boolean(
        default=True,
        doc=(
            "Whether to automatically convert value and event keys to snake_case for convenience. "
            "However, this can slow down the widget if there are many events or if the events are large."
        ),
    )

    event_max_stack = param.Integer(
        default=None,
        doc="For timeline view, the maximum number of events that stack top-to-bottom. For timeGrid view, the maximum number of events that stack left-to-right.",
    )

    event_order = param.String(
        default="start,-duration,title,allDay",
        doc="Determines the ordering events within the same day.",
    )

    event_order_strict = param.Boolean(
        default=False,
        doc="Ensures the eventOrder setting is strictly followed.",
    )

    event_remove_callback = param.Callable(
        default=None,
        doc="Triggered when an event is removed.",
    )

    event_resize_callback = param.Callable(
        default=None,
        doc="Triggered when resizing stops and the event has changed in duration.",
    )

    event_resize_start_callback = param.Callable(
        default=None,
        doc="Triggered when event resizing begins.",
    )

    event_resize_stop_callback = param.Callable(
        default=None,
        doc="Triggered when event resizing stops.",
    )

    event_resizable_from_start = param.Boolean(
        default=True,
        doc="Whether the user can resize an event from its starting edge.",
    )

    event_start_editable = param.Boolean(
        default=True,
        doc="Allow events' start times to be editable through dragging.",
    )

    event_text_color = param.Color(
        default=None,
        doc="Sets the text color for all events on the calendar.",
    )

    event_time_format = param.Dict(
        default=None,
        doc="Determines the time-text that will be displayed on each event.",
    )

    expand_rows = param.Boolean(
        default=False,
        doc="If the rows of a given view don't take up the entire height, they will expand to fit.",
    )

    footer_toolbar = param.Dict(default={}, doc="Defines the buttons and title at the bottom of the calendar.")

    handle_window_resize = param.Boolean(
        default=True,
        doc="Whether to automatically resize the calendar when the browser window resizes.",
    )

    header_toolbar = param.Dict(
        default={
            "left": "prev,next today",
            "center": "title",
            "right": "dayGridMonth,timeGridWeek,timeGridDay",
        },
        doc="Defines the buttons and title at the top of the calendar.",
    )

    more_link_click = param.String(
        default="popover",
        doc='Determines the action taken when the user clicks on a "more" link created by the dayMaxEventRows or dayMaxEvents options.',
    )

    multi_month_max_columns = param.Integer(
        default=1,
        doc="Determines the maximum number of columns in the multi-month view.",
    )

    nav_links = param.Boolean(
        default=True,
        doc="Turns various datetime text into clickable links that the user can use for navigation.",
    )

    next_day_threshold = param.String(
        default="00:00:00",
        doc="When an event's end time spans into another day, the minimum time it must be in order for it to render as if it were on that day.",
    )

    now_indicator = param.Boolean(default=True, doc="Whether to display an indicator for the current time.")

    progressive_event_rendering = param.Boolean(
        default=False,
        doc="When to render multiple asynchronous event sources in an individual or batched manner.",
    )

    selectable = param.Boolean(
        default=False,
        doc="Allows a user to highlight multiple days or timeslots by clicking and dragging.",
    )

    select_callback = param.Callable(
        default=None,
        doc="A callback that will be called when a selection is made.",
    )

    select_mirror = param.Boolean(
        default=False,
        doc="Whether to draw a 'placeholder' event while the user is dragging.",
    )

    unselect_auto = param.Boolean(
        default=True,
        doc="Whether clicking elsewhere on the page will cause the current selection to be cleared.",
    )

    unselect_cancel = param.String(
        default=None,
        doc="A way to specify elements that will ignore the unselectAuto option.",
    )

    select_allow = param.Callable(
        default=None,
        doc="Exact programmatic control over where the user can select.",
    )

    select_min_distance = param.Integer(
        default=0,
        doc="The minimum distance the user's mouse must travel after a mousedown, before a selection is allowed.",
    )

    show_non_current_dates = param.Boolean(
        default=False,
        doc="Whether to display dates in the current view that don't belong to the current month.",
    )

    snap_duration = param.String(
        default=None,
        doc="The time interval at which a dragged event will snap to the time axis. Also affects the granularity at which selections can be made.",
    )

    sticky_footer_scrollbar = param.Boolean(
        default=True,
        doc="Whether to fix the view's horizontal scrollbar to the bottom of the viewport while scrolling.",
    )

    sticky_header_dates = param.String(
        default=None,
        doc="Whether to fix the date-headers at the top of the calendar to the viewport while scrolling.",
    )

    time_zone = param.String(
        default="local",
        doc="Determines the time zone the calendar will use to display dates.",
    )

    title_format = param.Dict(
        default=None,
        doc="Determines the text that will be displayed in the header toolbar's title.",
    )

    title_range_separator = param.String(
        default=" to ",
        doc="Determines the separator text when formatting the date range in the toolbar title.",
    )

    unselect_callback = param.Callable(
        default=None,
        doc="A callback that will be called when a selection is cleared.",
    )

    valid_range = param.Dict(
        default=None,
        doc=("Dates outside of the valid range will be grayed-out and inaccessible. " "Can have `start` and `end` keys, but both do not need to be together."),
    )

    value = param.List(default=[], item_type=dict, doc="List of events to display on the calendar.")

    views = param.Dict(
        default={},
        doc=("Options to pass to only to specific calendar views. " "Provide separate options objects within the views option, keyed by the name of your view."),
    )

    window_resize_delay = param.Integer(
        default=100,
        doc="The time the calendar will wait to adjust its size after a window resize occurs, in milliseconds.",
    )

    _esm = MODELS_DIR / "fullcalendar.js"

    _rename = {
        # callbacks are handled in _handle_msg getattr
        "current_date_callback": None,
        "current_view_callback": None,
        "date_click_callback": None,
        "event_change_callback": None,
        "event_click_callback": None,
        "event_drag_start_callback": None,
        "event_drag_stop_callback": None,
        "event_drop_callback": None,
        "event_remove_callback": None,
        "event_resize_callback": None,
        "event_resize_start_callback": None,
        "event_resize_stop_callback": None,
        "select_callback": None,
        "unselect_callback": None,
        "events_in_view": None,
    }

    _importmap = {
        "imports": {
            "@fullcalendar/core": "https://cdn.skypack.dev/@fullcalendar/core@6.1.15",
            "@fullcalendar/daygrid": "https://cdn.skypack.dev/@fullcalendar/daygrid@6.1.15",
            "@fullcalendar/timegrid": "https://cdn.skypack.dev/@fullcalendar/timegrid@6.1.15",
            "@fullcalendar/list": "https://cdn.skypack.dev/@fullcalendar/list@6.1.15",
            "@fullcalendar/multimonth": "https://cdn.skypack.dev/@fullcalendar/multimonth@6.1.15",
            "@fullcalendar/interaction": "https://cdn.skypack.dev/@fullcalendar/interaction@6.1.15",
        }
    }

    def __init__(self, **params):
        """Create a new Calendar widget."""
        super().__init__(**params)
        self._assign_id_to_events()

        self._buffer = []
        self.param.watch(
            self._update_options,
            [
                "all_day_maintain_duration",
                "aspect_ratio",
                "business_hours",
                "button_icons",
                "button_text",
                "date_alignment",
                "date_delta",
                "day_max_event_rows",
                "day_max_events",
                "day_popover_format",
                "display_event_end",
                "display_event_time",
                "drag_revert_duration",
                "drag_scroll",
                "editable",
                "event_background_color",
                "event_border_color",
                "event_color",
                "event_display",
                "event_drag_min_distance",
                "event_duration_editable",
                "event_max_stack",
                "event_order",
                "event_order_strict",
                "event_resizable_from_start",
                "event_start_editable",
                "event_text_color",
                "event_time_format",
                "expand_rows",
                "footer_toolbar",
                "handle_window_resize",
                "header_toolbar",
                "more_link_click",
                "multi_month_max_columns",
                "nav_links",
                "next_day_threshold",
                "now_indicator",
                "progressive_event_rendering",
                "selectable",
                "select_mirror",
                "unselect_auto",
                "unselect_cancel",
                "select_allow",
                "select_min_distance",
                "show_non_current_dates",
                "snap_duration",
                "sticky_footer_scrollbar",
                "sticky_header_dates",
                "time_zone",
                "title_format",
                "title_range_separator",
                "valid_range",
                "value",
                "window_resize_delay",
            ],
        )

    def click_next(self) -> None:
        """Click the next button through the calendar's UI."""
        self._send_msg({"type": "next"})

    def click_prev(self) -> None:
        """Click the previous button through the calendar's UI."""
        self._send_msg({"type": "prev"})

    def click_prev_year(self) -> None:
        """Click the previous year button through the calendar's UI."""
        self._send_msg({"type": "prevYear"})

    def click_next_year(self) -> None:
        """Click the next year button through the calendar's UI."""
        self._send_msg({"type": "nextYear"})

    def click_today(self) -> None:
        """Click the today button through the calendar's UI."""
        self._send_msg({"type": "today"})

    def change_view(
        self,
        view: str,
        date: str | datetime.datetime | datetime.date | int | None = None,
    ) -> None:
        """
        Change the current view of the calendar, and optionally go to a specific date.

        Args:
            view: The view to change to.
                Options: "dayGridMonth", "dayGridWeek", "dayGridDay", "timeGridWeek", "timeGridDay",
                "listWeek", "listMonth", "listYear", "multiMonthYear".
            date: The date to go to after changing the view; if None, the current date will be used.
                Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
        """
        self._send_msg({"type": "changeView", "view": view, "date": date})

    def go_to_date(self, date: str | datetime.datetime | datetime.date | int) -> None:
        """
        Go to a specific date on the calendar.

        Args:
            date: The date to go to.
                Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
        """
        self._send_msg({"type": "gotoDate", "date": date})

    def delta_date(self, delta: str | datetime.timedelta | int | dict | None = None) -> None:
        """
        delta the current date by a specific amount.

        Args:
            delta: The amount to delta the current date by.
                Supports a string in the format hh:mm:ss.sss, hh:mm:sss or hh:mm, an int in milliseconds,
                datetime.timedelta objects, or a dict with any of the following keys:
                    year, years, month, months, day, days, minute, minutes, second,
                    seconds, millisecond, milliseconds, ms.
                If not provided, the date_delta parameter will be used.
                If date_delta is not set, the default delta for the current view will be used:
                    dayGridMonth: {"days": 1}
                    dayGridWeek: {"weeks": 1}
                    dayGridDay: {"days": 1}
                    timeGridWeek: {"weeks": 1}
                    timeGridDay: {"days": 1}
                    listWeek: {"weeks": 1}
                    listMonth: {"months": 1}
                    listYear: {"years": 1}
                    multiMonthYear: {"years": 1}
        """
        if delta is None and self.date_delta is None:
            delta = VIEW_DEFAULT_deltaS[self.current_view]
        self._send_msg({"type": "deltaDate", "delta": delta})

    def scroll_to_time(self, time: str | datetime.time | int) -> None:
        """
        Scroll the calendar to a specific time.

        Args:
            time: The time to scroll to.
                Supports ISO 8601 time strings, datetime.time objects, and int in milliseconds.
        """
        self._send_msg({"type": "scrollToTime", "time": time})

    def add_event(
        self,
        start: str | datetime.datetime | datetime.date | int | None = None,
        end: str | datetime.datetime | datetime.date | int | None = None,
        title: str | None = "(no title)",
        all_day: bool | None = None,
        display: Literal["background", "inverse-background"] | None = None,
        **kwargs,
    ) -> None:
        """
        Add an event to the calendar.

        Args:
            start: The start of the event.
                Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
            end: The end of the event.
                Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
                If None, the event will be all-day.
            title: The title of the event.
            all_day: Whether the event is an all-day event.
            display: How the event should be displayed. Options: "background", "inverse-background".
            **kwargs: Additional properties to set on the event. Takes precedence over other arguments.
        """
        if self.event_keys_auto_camel_case:
            kwargs = to_camel_case_keys(kwargs)

        event = {}
        if start is not None:
            event["start"] = start
        if end is not None:
            event["end"] = end
        if title is not None:
            event["title"] = title
        if all_day is not None:
            event["allDay"] = all_day
        if display is not None:
            event["display"] = display
        event.update(kwargs)
        self.value = self.value + [event]

    def add_events(self, events: list[dict]) -> None:
        """
        Add multiple events to the calendar.

        Args:
            events: A list of events to add to the calendar.
        """
        with param.parameterized.batch_call_watchers(self):
            for event in events:
                self.add_event(**event)

    def get_event_in_view(
        self,
        start: str | datetime.datetime | datetime.date | int,
        title: str,
        match_by_time: bool = False,
    ) -> "CalendarEvent":
        """
        Get an event from the calendar.

        Args:
            start: The start of the event.
                Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
            title: The title of the event.
            match_by_time: Whether to match the start time exactly, or by date only.

        Returns:
            Event: The event with the given start and title.
        """
        for event in self.events_in_view:  # type: ignore
            norm_start, event_start = normalize_datetimes(start, event["start"])  # type: ignore
            if match_by_time:
                norm_start = norm_start.date()
                event_start = event_start.date()
            if norm_start != event_start or event["title"] != title:
                continue
            return CalendarEvent(
                id=event["id"],
                title=event["title"],
                start=event["start"],
                end=event.get("end"),
                all_day=event.get("allDay"),
                calendar=self,
            )
        raise ValueError(f"No event found with start {start} and title {title}.")

    def clear_events(self) -> None:
        """Clear all events from the calendar."""
        self.value = []

    def _handle_msg(self, msg):
        if "events_in_view" in msg:
            events = json.loads(msg["events_in_view"])
            with param.edit_constant(self):
                self.events_in_view = events
        elif "current_date" in msg:
            current_date_info = json.loads(msg["current_date"])
            with param.edit_constant(self):
                self.current_date = current_date_info["startStr"]
            if self.current_date_callback:
                self.current_date_callback(current_date_info)
        elif "current_view" in msg:
            current_view_info = json.loads(msg["current_view"])
            with param.edit_constant(self):
                self.current_view = current_view_info["view"]["type"]
            if self.current_view_callback:
                self.current_view_callback(current_view_info)
        else:
            key = list(msg.keys())[0]
            callback_name = f"{key}_callback"
            if hasattr(self, callback_name):
                info = json.loads(msg[key])
                if callback_name == "event_change_callback":
                    new_event = info["event"]
                    for value in self.value:
                        if value["id"] != new_event["id"]:
                            continue
                        value.update(new_event)
                        break
                    self.param.trigger("value")
                elif callback_name == "event_remove_callback":
                    removed_event = info["event"]
                    for value in self.value:
                        if value["id"] != removed_event["id"]:
                            continue
                        self.value.remove(value)
                        break
                    self.param.trigger("value")
                callback = getattr(self, callback_name)
                if callback:
                    callback(info)
            else:
                raise RuntimeError(f"Unhandled message: {msg}")

    def _update_options(self, *events):
        updates = [
            {
                "key": ("events" if to_camel_case(event.name) == "value" else to_camel_case(event.name)),
                "value": event.new,
            }
            for event in events
        ]
        self._send_msg({"type": "updateOptions", "updates": updates})

    def _assign_id_to_events(self):
        for event in self.value:
            event["id"] = event.get("id", str(id(event)))
            if self.event_keys_auto_camel_case:
                for key in list(event.keys()):
                    event[to_camel_case(key)] = event.pop(key)

    @param.depends("value", watch=True)
    async def _update_events_in_view(self):
        self._assign_id_to_events()
        await asyncio.sleep(0.001)  # needed to prevent race condition
        self._send_msg({"type": "updateEventsInView"})

all_day_maintain_duration = param.Boolean(default=False, doc="Determines how an event's duration should be mutated when it is dragged from a timed section to an all-day section and vice versa.") class-attribute instance-attribute

aspect_ratio = param.Number(default=None, doc='Sets the width-to-height aspect ratio of the calendar.') class-attribute instance-attribute

business_hours = param.Dict(default=None, doc='Emphasizes certain time slots on the calendar.') class-attribute instance-attribute

button_icons = param.Dict(default={}, doc='Icons that will be displayed in buttons of the header/footer toolbar.') class-attribute instance-attribute

button_text = param.Dict(default={}, doc='Text that will be displayed on buttons of the header/footer toolbar.') class-attribute instance-attribute

current_date = param.String(default=None, constant=True, doc='The onload or current date of the calendar view. Use go_to_date() to change the date.') class-attribute instance-attribute

current_date_callback = param.Callable(default=None, doc='A callback that will be called when the current date changes.') class-attribute instance-attribute

current_view = param.Selector(default='dayGridMonth', objects=['dayGridMonth', 'dayGridWeek', 'dayGridDay', 'timeGridWeek', 'timeGridDay', 'listWeek', 'listMonth', 'listYear', 'multiMonthYear'], constant=True, doc='The onload or current view of the calendar. Use change_view() to change the view.') class-attribute instance-attribute

current_view_callback = param.Callable(default=None, doc='A callback that will be called when the current view changes.') class-attribute instance-attribute

date_alignment = param.String(default=None, doc='Determines how certain views should be initially aligned.') class-attribute instance-attribute

date_click_callback = param.Callable(default=None, doc='A callback that will be called when a date is clicked.') class-attribute instance-attribute

date_delta = param.String(default=None, doc='The duration to move forward/backward when prev/next is clicked.') class-attribute instance-attribute

day_max_event_rows = param.Integer(default=False, doc='In dayGrid view, the max number of stacked event levels within a given day. This includes the +more link if present. The rest will show up in a popover.') class-attribute instance-attribute

day_max_events = param.Integer(default=None, doc='In dayGrid view, the max number of events within a given day, not counting the +more link. The rest will show up in a popover.') class-attribute instance-attribute

day_popover_format = param.Dict(default=None, doc='Determines the date format of title of the popover created by the moreLinkClick option.') class-attribute instance-attribute

display_event_end = param.Boolean(default=None, doc="Whether or not to display an event's end time.") class-attribute instance-attribute

display_event_time = param.Boolean(default=True, doc="Whether or not to display the text for an event's date/time.") class-attribute instance-attribute

drag_revert_duration = param.Integer(default=500, doc='Time it takes for an event to revert to its original position after an unsuccessful drag.') class-attribute instance-attribute

drag_scroll = param.Boolean(default=True, doc='Whether to automatically scroll the scroll-containers during event drag-and-drop and date selecting.') class-attribute instance-attribute

editable = param.Boolean(default=False, doc='Determines whether the events on the calendar can be modified.') class-attribute instance-attribute

event_background_color = param.Color(default=None, doc='Sets the background color for all events on the calendar.') class-attribute instance-attribute

event_border_color = param.Color(default=None, doc='Sets the border color for all events on the calendar.') class-attribute instance-attribute

event_change_callback = param.Callable(default=None, doc='A callback that will be called when an event is changed.') class-attribute instance-attribute

event_click_callback = param.Callable(default=None, doc='A callback that will be called when an event is clicked.') class-attribute instance-attribute

event_color = param.Color(default=None, doc='Sets the background and border colors for all events on the calendar.') class-attribute instance-attribute

event_display = param.String(default='auto', doc='Controls which preset rendering style events use.') class-attribute instance-attribute

event_drag_min_distance = param.Integer(default=5, doc="How many pixels the user's mouse/touch must move before an event drag activates.") class-attribute instance-attribute

event_drag_start_callback = param.Callable(default=None, doc='Triggered when event dragging begins.') class-attribute instance-attribute

event_drag_stop_callback = param.Callable(default=None, doc='Triggered when event dragging stops.') class-attribute instance-attribute

event_drop_callback = param.Callable(default=None, doc='Triggered when dragging stops and the event has moved to a different day/time.') class-attribute instance-attribute

event_duration_editable = param.Boolean(default=True, doc="Allow events' durations to be editable through resizing.") class-attribute instance-attribute

event_keys_auto_camel_case = param.Boolean(default=True, doc='Whether to automatically convert value and event keys to camelCase for convenience. However, this can slow down the widget if there are many events or if the events are large.') class-attribute instance-attribute

event_keys_auto_snake_case = param.Boolean(default=True, doc='Whether to automatically convert value and event keys to snake_case for convenience. However, this can slow down the widget if there are many events or if the events are large.') class-attribute instance-attribute

event_max_stack = param.Integer(default=None, doc='For timeline view, the maximum number of events that stack top-to-bottom. For timeGrid view, the maximum number of events that stack left-to-right.') class-attribute instance-attribute

event_order = param.String(default='start,-duration,title,allDay', doc='Determines the ordering events within the same day.') class-attribute instance-attribute

event_order_strict = param.Boolean(default=False, doc='Ensures the eventOrder setting is strictly followed.') class-attribute instance-attribute

event_remove_callback = param.Callable(default=None, doc='Triggered when an event is removed.') class-attribute instance-attribute

event_resizable_from_start = param.Boolean(default=True, doc='Whether the user can resize an event from its starting edge.') class-attribute instance-attribute

event_resize_callback = param.Callable(default=None, doc='Triggered when resizing stops and the event has changed in duration.') class-attribute instance-attribute

event_resize_start_callback = param.Callable(default=None, doc='Triggered when event resizing begins.') class-attribute instance-attribute

event_resize_stop_callback = param.Callable(default=None, doc='Triggered when event resizing stops.') class-attribute instance-attribute

event_start_editable = param.Boolean(default=True, doc="Allow events' start times to be editable through dragging.") class-attribute instance-attribute

event_text_color = param.Color(default=None, doc='Sets the text color for all events on the calendar.') class-attribute instance-attribute

event_time_format = param.Dict(default=None, doc='Determines the time-text that will be displayed on each event.') class-attribute instance-attribute

events_in_view = param.List(default=[], doc='List of events that are currently in view on the calendar.', constant=True) class-attribute instance-attribute

expand_rows = param.Boolean(default=False, doc="If the rows of a given view don't take up the entire height, they will expand to fit.") class-attribute instance-attribute

footer_toolbar = param.Dict(default={}, doc='Defines the buttons and title at the bottom of the calendar.') class-attribute instance-attribute

handle_window_resize = param.Boolean(default=True, doc='Whether to automatically resize the calendar when the browser window resizes.') class-attribute instance-attribute

header_toolbar = param.Dict(default={'left': 'prev,next today', 'center': 'title', 'right': 'dayGridMonth,timeGridWeek,timeGridDay'}, doc='Defines the buttons and title at the top of the calendar.') class-attribute instance-attribute

multi_month_max_columns = param.Integer(default=1, doc='Determines the maximum number of columns in the multi-month view.') class-attribute instance-attribute

next_day_threshold = param.String(default='00:00:00', doc="When an event's end time spans into another day, the minimum time it must be in order for it to render as if it were on that day.") class-attribute instance-attribute

now_indicator = param.Boolean(default=True, doc='Whether to display an indicator for the current time.') class-attribute instance-attribute

progressive_event_rendering = param.Boolean(default=False, doc='When to render multiple asynchronous event sources in an individual or batched manner.') class-attribute instance-attribute

select_allow = param.Callable(default=None, doc='Exact programmatic control over where the user can select.') class-attribute instance-attribute

select_callback = param.Callable(default=None, doc='A callback that will be called when a selection is made.') class-attribute instance-attribute

select_min_distance = param.Integer(default=0, doc="The minimum distance the user's mouse must travel after a mousedown, before a selection is allowed.") class-attribute instance-attribute

select_mirror = param.Boolean(default=False, doc="Whether to draw a 'placeholder' event while the user is dragging.") class-attribute instance-attribute

selectable = param.Boolean(default=False, doc='Allows a user to highlight multiple days or timeslots by clicking and dragging.') class-attribute instance-attribute

show_non_current_dates = param.Boolean(default=False, doc="Whether to display dates in the current view that don't belong to the current month.") class-attribute instance-attribute

snap_duration = param.String(default=None, doc='The time interval at which a dragged event will snap to the time axis. Also affects the granularity at which selections can be made.') class-attribute instance-attribute

sticky_header_dates = param.String(default=None, doc='Whether to fix the date-headers at the top of the calendar to the viewport while scrolling.') class-attribute instance-attribute

time_zone = param.String(default='local', doc='Determines the time zone the calendar will use to display dates.') class-attribute instance-attribute

title_format = param.Dict(default=None, doc="Determines the text that will be displayed in the header toolbar's title.") class-attribute instance-attribute

title_range_separator = param.String(default=' to ', doc='Determines the separator text when formatting the date range in the toolbar title.') class-attribute instance-attribute

unselect_auto = param.Boolean(default=True, doc='Whether clicking elsewhere on the page will cause the current selection to be cleared.') class-attribute instance-attribute

unselect_callback = param.Callable(default=None, doc='A callback that will be called when a selection is cleared.') class-attribute instance-attribute

unselect_cancel = param.String(default=None, doc='A way to specify elements that will ignore the unselectAuto option.') class-attribute instance-attribute

valid_range = param.Dict(default=None, doc='Dates outside of the valid range will be grayed-out and inaccessible. Can have `start` and `end` keys, but both do not need to be together.') class-attribute instance-attribute

value = param.List(default=[], item_type=dict, doc='List of events to display on the calendar.') class-attribute instance-attribute

views = param.Dict(default={}, doc='Options to pass to only to specific calendar views. Provide separate options objects within the views option, keyed by the name of your view.') class-attribute instance-attribute

window_resize_delay = param.Integer(default=100, doc='The time the calendar will wait to adjust its size after a window resize occurs, in milliseconds.') class-attribute instance-attribute

add_event(start=None, end=None, title='(no title)', all_day=None, display=None, **kwargs)

Add an event to the calendar.

Parameters:

Name Type Description Default
start str | datetime | date | int | None

The start of the event. Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.

None
end str | datetime | date | int | None

The end of the event. Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds. If None, the event will be all-day.

None
title str | None

The title of the event.

'(no title)'
all_day bool | None

Whether the event is an all-day event.

None
display Literal['background', 'inverse-background'] | None

How the event should be displayed. Options: "background", "inverse-background".

None
**kwargs

Additional properties to set on the event. Takes precedence over other arguments.

{}
Source code in src/panel_full_calendar/main.py
def add_event(
    self,
    start: str | datetime.datetime | datetime.date | int | None = None,
    end: str | datetime.datetime | datetime.date | int | None = None,
    title: str | None = "(no title)",
    all_day: bool | None = None,
    display: Literal["background", "inverse-background"] | None = None,
    **kwargs,
) -> None:
    """
    Add an event to the calendar.

    Args:
        start: The start of the event.
            Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
        end: The end of the event.
            Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
            If None, the event will be all-day.
        title: The title of the event.
        all_day: Whether the event is an all-day event.
        display: How the event should be displayed. Options: "background", "inverse-background".
        **kwargs: Additional properties to set on the event. Takes precedence over other arguments.
    """
    if self.event_keys_auto_camel_case:
        kwargs = to_camel_case_keys(kwargs)

    event = {}
    if start is not None:
        event["start"] = start
    if end is not None:
        event["end"] = end
    if title is not None:
        event["title"] = title
    if all_day is not None:
        event["allDay"] = all_day
    if display is not None:
        event["display"] = display
    event.update(kwargs)
    self.value = self.value + [event]

add_events(events)

Add multiple events to the calendar.

Parameters:

Name Type Description Default
events list[dict]

A list of events to add to the calendar.

required
Source code in src/panel_full_calendar/main.py
def add_events(self, events: list[dict]) -> None:
    """
    Add multiple events to the calendar.

    Args:
        events: A list of events to add to the calendar.
    """
    with param.parameterized.batch_call_watchers(self):
        for event in events:
            self.add_event(**event)

change_view(view, date=None)

Change the current view of the calendar, and optionally go to a specific date.

Parameters:

Name Type Description Default
view str

The view to change to. Options: "dayGridMonth", "dayGridWeek", "dayGridDay", "timeGridWeek", "timeGridDay", "listWeek", "listMonth", "listYear", "multiMonthYear".

required
date str | datetime | date | int | None

The date to go to after changing the view; if None, the current date will be used. Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.

None
Source code in src/panel_full_calendar/main.py
def change_view(
    self,
    view: str,
    date: str | datetime.datetime | datetime.date | int | None = None,
) -> None:
    """
    Change the current view of the calendar, and optionally go to a specific date.

    Args:
        view: The view to change to.
            Options: "dayGridMonth", "dayGridWeek", "dayGridDay", "timeGridWeek", "timeGridDay",
            "listWeek", "listMonth", "listYear", "multiMonthYear".
        date: The date to go to after changing the view; if None, the current date will be used.
            Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
    """
    self._send_msg({"type": "changeView", "view": view, "date": date})

clear_events()

Clear all events from the calendar.

Source code in src/panel_full_calendar/main.py
def clear_events(self) -> None:
    """Clear all events from the calendar."""
    self.value = []

click_next()

Click the next button through the calendar's UI.

Source code in src/panel_full_calendar/main.py
def click_next(self) -> None:
    """Click the next button through the calendar's UI."""
    self._send_msg({"type": "next"})

click_next_year()

Click the next year button through the calendar's UI.

Source code in src/panel_full_calendar/main.py
def click_next_year(self) -> None:
    """Click the next year button through the calendar's UI."""
    self._send_msg({"type": "nextYear"})

click_prev()

Click the previous button through the calendar's UI.

Source code in src/panel_full_calendar/main.py
def click_prev(self) -> None:
    """Click the previous button through the calendar's UI."""
    self._send_msg({"type": "prev"})

click_prev_year()

Click the previous year button through the calendar's UI.

Source code in src/panel_full_calendar/main.py
def click_prev_year(self) -> None:
    """Click the previous year button through the calendar's UI."""
    self._send_msg({"type": "prevYear"})

click_today()

Click the today button through the calendar's UI.

Source code in src/panel_full_calendar/main.py
def click_today(self) -> None:
    """Click the today button through the calendar's UI."""
    self._send_msg({"type": "today"})

delta_date(delta=None)

delta the current date by a specific amount.

Parameters:

Name Type Description Default
delta str | timedelta | int | dict | None

The amount to delta the current date by. Supports a string in the format hh:mm:ss.sss, hh:mm:sss or hh:mm, an int in milliseconds, datetime.timedelta objects, or a dict with any of the following keys: year, years, month, months, day, days, minute, minutes, second, seconds, millisecond, milliseconds, ms. If not provided, the date_delta parameter will be used. If date_delta is not set, the default delta for the current view will be used: dayGridMonth: {"days": 1} dayGridWeek: {"weeks": 1} dayGridDay: {"days": 1} timeGridWeek: {"weeks": 1} timeGridDay: {"days": 1} listWeek: {"weeks": 1} listMonth: {"months": 1} listYear: {"years": 1} multiMonthYear: {"years": 1}

None
Source code in src/panel_full_calendar/main.py
def delta_date(self, delta: str | datetime.timedelta | int | dict | None = None) -> None:
    """
    delta the current date by a specific amount.

    Args:
        delta: The amount to delta the current date by.
            Supports a string in the format hh:mm:ss.sss, hh:mm:sss or hh:mm, an int in milliseconds,
            datetime.timedelta objects, or a dict with any of the following keys:
                year, years, month, months, day, days, minute, minutes, second,
                seconds, millisecond, milliseconds, ms.
            If not provided, the date_delta parameter will be used.
            If date_delta is not set, the default delta for the current view will be used:
                dayGridMonth: {"days": 1}
                dayGridWeek: {"weeks": 1}
                dayGridDay: {"days": 1}
                timeGridWeek: {"weeks": 1}
                timeGridDay: {"days": 1}
                listWeek: {"weeks": 1}
                listMonth: {"months": 1}
                listYear: {"years": 1}
                multiMonthYear: {"years": 1}
    """
    if delta is None and self.date_delta is None:
        delta = VIEW_DEFAULT_deltaS[self.current_view]
    self._send_msg({"type": "deltaDate", "delta": delta})

get_event_in_view(start, title, match_by_time=False)

Get an event from the calendar.

Parameters:

Name Type Description Default
start str | datetime | date | int

The start of the event. Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.

required
title str

The title of the event.

required
match_by_time bool

Whether to match the start time exactly, or by date only.

False

Returns:

Name Type Description
Event CalendarEvent

The event with the given start and title.

Source code in src/panel_full_calendar/main.py
def get_event_in_view(
    self,
    start: str | datetime.datetime | datetime.date | int,
    title: str,
    match_by_time: bool = False,
) -> "CalendarEvent":
    """
    Get an event from the calendar.

    Args:
        start: The start of the event.
            Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
        title: The title of the event.
        match_by_time: Whether to match the start time exactly, or by date only.

    Returns:
        Event: The event with the given start and title.
    """
    for event in self.events_in_view:  # type: ignore
        norm_start, event_start = normalize_datetimes(start, event["start"])  # type: ignore
        if match_by_time:
            norm_start = norm_start.date()
            event_start = event_start.date()
        if norm_start != event_start or event["title"] != title:
            continue
        return CalendarEvent(
            id=event["id"],
            title=event["title"],
            start=event["start"],
            end=event.get("end"),
            all_day=event.get("allDay"),
            calendar=self,
        )
    raise ValueError(f"No event found with start {start} and title {title}.")

go_to_date(date)

Go to a specific date on the calendar.

Parameters:

Name Type Description Default
date str | datetime | date | int

The date to go to. Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.

required
Source code in src/panel_full_calendar/main.py
def go_to_date(self, date: str | datetime.datetime | datetime.date | int) -> None:
    """
    Go to a specific date on the calendar.

    Args:
        date: The date to go to.
            Supports ISO 8601 date strings, datetime/date objects, and int in milliseconds.
    """
    self._send_msg({"type": "gotoDate", "date": date})

scroll_to_time(time)

Scroll the calendar to a specific time.

Parameters:

Name Type Description Default
time str | time | int

The time to scroll to. Supports ISO 8601 time strings, datetime.time objects, and int in milliseconds.

required
Source code in src/panel_full_calendar/main.py
def scroll_to_time(self, time: str | datetime.time | int) -> None:
    """
    Scroll the calendar to a specific time.

    Args:
        time: The time to scroll to.
            Supports ISO 8601 time strings, datetime.time objects, and int in milliseconds.
    """
    self._send_msg({"type": "scrollToTime", "time": time})

CalendarEvent

Bases: Parameterized

A class representing an event on a Calendar.

Source code in src/panel_full_calendar/main.py
class CalendarEvent(param.Parameterized):
    """A class representing an event on a Calendar."""

    id: str = param.String(default=None, doc="A unique identifier for the event.", constant=True)

    start = param.String(
        default=None,
        constant=True,
        doc="The start of the event. Supports ISO 8601 date strings. Use `set_start` to change.",
    )

    end = param.String(
        default=None,
        constant=True,
        doc="The end of the event. Supports ISO 8601 date strings. Use `set_end` to change.",
    )

    title = param.String(
        default="(no title)",
        constant=True,
        doc="The title of the event. Use `set_props` to change.",
    )

    all_day = param.Boolean(
        default=False,
        constant=True,
        doc="Whether the event is an all-day event. Use `set_props` to change.",
    )

    props = param.Dict(
        default={},
        constant=True,
        doc="Additional properties of the event. Use `set_props` to change.",
    )

    calendar = param.ClassSelector(
        class_=Calendar,
        constant=True,
        doc="The calendar that the event belongs to.",
    )

    def remove(self):
        """Remove the event from the calendar."""
        self.calendar._send_msg({"type": "removeEvent", "id": self.id})

    def set_props(self, **kwargs):
        """Modifies any of the non-date-related properties of the event."""
        updates = kwargs.copy()
        if self.calendar.event_keys_auto_camel_case:
            updates = to_camel_case_keys(kwargs)

        self.calendar._send_msg({"type": "setProp", "id": self.id, "updates": updates})
        with param.edit_constant(self):
            if "title" in kwargs:
                self.title = kwargs.pop("title")
            if "allDay" in kwargs:
                self.all_day = kwargs.pop("allDay")
            self.props.update(kwargs)

    def set_start(self, start: str | datetime.datetime | datetime.date | int):
        """Update the start of the event."""
        self.calendar._send_msg({"type": "setStart", "id": self.id, "updates": {"start": start}})
        with param.edit_constant(self):
            self.start = start

    def set_end(self, end: str | datetime.datetime | datetime.date | int):
        """Update the end of the event."""
        self.calendar._send_msg({"type": "setEnd", "id": self.id, "updates": {"end": end}})
        with param.edit_constant(self):
            self.end = end

    @classmethod
    def from_dict(cls, event_dict: dict, calendar: Calendar):
        """
        Create a CalendarEvent from a dictionary.

        Args:
            event_dict: A dictionary representing the event.
            calendar: The calendar that the event belongs to.

        Returns:
            CalendarEvent: The event.
        """
        return cls(
            id=event_dict.pop("id"),
            title=event_dict.pop("title", "(no title)"),
            start=event_dict.pop("start"),
            end=event_dict.pop("end", None),
            all_day=event_dict.pop("allDay", False),
            props=event_dict,
            calendar=calendar,
        )

    def __repr__(self):
        """Return a simplified string representation of the event."""
        attributes = [f"{p[0]}={p[1]}" for p in self.param.get_param_values() if p[1] is not None and p[0] not in ("calendar", "name")]
        attributes_str = ", ".join(attributes)
        return f"CalendarEvent({attributes_str})"

all_day = param.Boolean(default=False, constant=True, doc='Whether the event is an all-day event. Use `set_props` to change.') class-attribute instance-attribute

calendar = param.ClassSelector(class_=Calendar, constant=True, doc='The calendar that the event belongs to.') class-attribute instance-attribute

end = param.String(default=None, constant=True, doc='The end of the event. Supports ISO 8601 date strings. Use `set_end` to change.') class-attribute instance-attribute

id: str = param.String(default=None, doc='A unique identifier for the event.', constant=True) class-attribute instance-attribute

props = param.Dict(default={}, constant=True, doc='Additional properties of the event. Use `set_props` to change.') class-attribute instance-attribute

start = param.String(default=None, constant=True, doc='The start of the event. Supports ISO 8601 date strings. Use `set_start` to change.') class-attribute instance-attribute

title = param.String(default='(no title)', constant=True, doc='The title of the event. Use `set_props` to change.') class-attribute instance-attribute

from_dict(event_dict, calendar) classmethod

Create a CalendarEvent from a dictionary.

Parameters:

Name Type Description Default
event_dict dict

A dictionary representing the event.

required
calendar Calendar

The calendar that the event belongs to.

required

Returns:

Name Type Description
CalendarEvent

The event.

Source code in src/panel_full_calendar/main.py
@classmethod
def from_dict(cls, event_dict: dict, calendar: Calendar):
    """
    Create a CalendarEvent from a dictionary.

    Args:
        event_dict: A dictionary representing the event.
        calendar: The calendar that the event belongs to.

    Returns:
        CalendarEvent: The event.
    """
    return cls(
        id=event_dict.pop("id"),
        title=event_dict.pop("title", "(no title)"),
        start=event_dict.pop("start"),
        end=event_dict.pop("end", None),
        all_day=event_dict.pop("allDay", False),
        props=event_dict,
        calendar=calendar,
    )

remove()

Remove the event from the calendar.

Source code in src/panel_full_calendar/main.py
def remove(self):
    """Remove the event from the calendar."""
    self.calendar._send_msg({"type": "removeEvent", "id": self.id})

set_end(end)

Update the end of the event.

Source code in src/panel_full_calendar/main.py
def set_end(self, end: str | datetime.datetime | datetime.date | int):
    """Update the end of the event."""
    self.calendar._send_msg({"type": "setEnd", "id": self.id, "updates": {"end": end}})
    with param.edit_constant(self):
        self.end = end

set_props(**kwargs)

Modifies any of the non-date-related properties of the event.

Source code in src/panel_full_calendar/main.py
def set_props(self, **kwargs):
    """Modifies any of the non-date-related properties of the event."""
    updates = kwargs.copy()
    if self.calendar.event_keys_auto_camel_case:
        updates = to_camel_case_keys(kwargs)

    self.calendar._send_msg({"type": "setProp", "id": self.id, "updates": updates})
    with param.edit_constant(self):
        if "title" in kwargs:
            self.title = kwargs.pop("title")
        if "allDay" in kwargs:
            self.all_day = kwargs.pop("allDay")
        self.props.update(kwargs)

set_start(start)

Update the start of the event.

Source code in src/panel_full_calendar/main.py
def set_start(self, start: str | datetime.datetime | datetime.date | int):
    """Update the start of the event."""
    self.calendar._send_msg({"type": "setStart", "id": self.id, "updates": {"start": start}})
    with param.edit_constant(self):
        self.start = start