PPowerApps UI
ComponentsLayoutsTemplatesAbout
P
PowerApps UI
Open Source

Production-ready UI components and patterns for Power Apps developers.

MIT License

Product

  • Components
  • Layouts
  • Templates
  • Starter Kits
  • About
  • Cheat Sheet
  • Documentation

Developers

  • Getting Started
  • Suggest Idea
  • Submit Component
  • Report Issues

Resources

  • Changelog
  • Newsletter
  • Best Practices
  • Design System
© 2026 PowerApps UI. Open source under MIT License.
Built byRodas Yonass
Privacy Policy•Terms of Service•MIT License
ComponentsCalendar Pro

Calendar Pro

Month, week and agenda views over a flat table of event occurrences. It reports the date window it is drawing so the host loads exactly that window — delegable and bounded no matter how large the list is — and raises events when a day or a chip is tapped. It writes nothing.

cmpCalendarPro.yaml
  1. 1. Go to the Components tab (right side panel, next to Screens)
  2. 2. Click New component — this creates a blank component
  3. 3. Click outside the new component to deselect it
  4. 4. Paste the YAML with Ctrl+V / ⌘V

This component requires Modern controls to be enabled. Settings → Updates → Preview → Modern controls and themes

Preview

August 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
ReviewsSite visitsDeadlinesTrainingLeave
OnRangeChange — Aug 1 → Sep 11 · 17 events

Month, week and agenda views over a flat table of event occurrences. Reports the date window it is drawing so the host loads only that window, and raises events when a day or an event is tapped.

It writes nothing and it does not expand recurrence. A repeating series arrives already materialised, one row per occurrence. That constraint is the reason it works against a real list rather than only against a demo collection.


The idea in one paragraph

Most Canvas calendars either compute occurrences at render time, which means no occurrence has a row you can attach an approval or a comment to, or they load the whole list and filter client side, which stops working at the delegation limit. This one does neither. It tells you which forty two days it is about to draw, you load exactly those, and it draws them. The query stays delegable and bounded no matter how large the list behind it is.


Properties

Input

PropertyTypeDefaultDescription
EventsTabletwo samplesFlat occurrences, one row per day an event appears on
ChannelsTablefive samplesCategories, with ChannelKey, Title, ColorHex
FocusDateDateAndTimeToday()Which month opens
ViewText"month"month, week or agenda. Read once, then the toolbar owns it
ConfigRecordsee belowLayout and behaviour, including DarkMode
ThemeTableDark and LightOne row per mode

Events table shape

ColumnTypeNotes
OccurrenceKeyTextUnique per occurrence. For a series, SeriesKey plus the date
OccurrenceDateDateThe day this row draws on. Index this column
StartDateTime
EndDateTime
IsAllDayBooleanAll day draws as a solid bar, timed as a tint
TitleText
ChannelKeyTextMatches Channels. No match falls back to the accent colour

A multi day event is several rows, one per day. See the contract for why.

Config

KeyDefaultDescription
RowHeight118Height of a week row in month view
ChipHeight20Height of one event chip
ChipSlots3Chips per day before the overflow link
ShowWeekNumberstrueISO week gutter
FirstDayOfWeek"Sunday"Sunday or Monday
HourStart7First hour drawn in week view
HourEnd19Last hour drawn
HourHeight52Height of one hour row
MarkHolidaystrueTint federal holidays in month view
DarkModefalsePicks a row of the Theme table
Accent""Hex string, blank uses the theme accent

Output

PropertyTypeDescription
RangeStartDateAndTimeFirst date drawn
RangeEndDateAndTimeLast date drawn
ActiveViewTextThe view currently drawn
SelectedDateDateAndTimeThe day last tapped
SelectedEventKeyTextThe chip last tapped, cleared when a day is tapped
VisibleCountNumberEvents inside the drawn range
FederalHolidaysTableObserved US federal dates for three years around the focus

Events

EventWhenRead
OnRangeChangeThe grid moved or the view changedRangeStart, RangeEnd
OnViewChangeThe view toggle was usedActiveView, then reload
OnSelectDayA day or an overflow link was tappedSelectedDate
OnSelectEventA chip was tappedSelectedEventKey, SelectedDate

Implementation details

RangeStart and RangeEnd follow the view. Week draws seven days and month draws forty two, so the toggle raises OnRangeChange as well as OnViewChange. A host that listens only for the view change reloads nothing and shows a week filtered to the month it was already holding.

One flat gallery per view, never nested. An inner gallery cannot read the outer ThisItem, and a control reading through a container returns a frozen value. The month grid is six rows of seven cells, each cell computing its own date from the row's WeekStart.

Overflow opens a day panel, it does not grow the cell. Growing would need the row height to change and the cell to hold as many chip slots as the busiest day might ever have. The panel shows every event on the day whatever the count, with room for full titles.

Chips carry a transparent button for the tooltip. ModernText has no Tooltip, so a title truncated to the cell width would be unreadable. The overlay supplies the tooltip, the tap, and a real keyboard focus stop.

Inactive views produce no rows. Hiding a gallery stops it being laid out but does not stop its Items evaluating, so each view's Items is gated on the active view. Without that, every toggle paid for all three.

Holidays use observed dates. Independence Day on a Saturday is observed on the Friday, and the Friday is the day that gets tinted.

Colour comes from the Theme table. A timed chip is a tint of its channel colour, and the tint amount is a theme value rather than a constant, which is what keeps it legible in both modes.


Use cases

SituationNotes
Panel and review schedulingChannels per review type, week view for the day plan
Reporting calendarMaterialise the recurring due dates, agenda view for the list
Inspection or site visit scheduleAll day events, month view
Leave and coverageAll day bars, one row per day of a leave block
Deadline overview across a programmeAgenda view, filtered by channel on the host
Training sessions with sign upOnSelectEvent opens your own detail, not the form

When not to use it. If you need resource columns, drag to reschedule, or overlapping events laid out side by side within an hour, this is not that component. It is a scheduling calendar, not a booking grid.


Examples

Load only the window it draws

On every range change, load exactly the dates drawn — delegable and bounded at ~42 rows, whatever the list size.

August 2026
S
M
T
W
T
F
S
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
OnRangeChange: |-
    =ClearCollect(
        colWindow,
        Filter(
            'Event Occurrences',
            OccurrenceDate >= cmpCalendarPro1.RangeStart,
            OccurrenceDate <= cmpCalendarPro1.RangeEnd
        )
    )
// then bind  Events: =colWindow

Open a form on a day tap

A day tap seeds a blank draft on that date and opens your Event Form. Reset is what loads it.

August 2026
S
M
T
W
T
F
S
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
OnSelectDay: |-
    =Set(gblFormEvent, {
        OccurrenceKey: "", Title: "", ChannelKey: "review",
        IsAllDay: false,
        Start: cmpCalendarPro1.SelectedDate + Time(9, 0, 0),
        End:   cmpCalendarPro1.SelectedDate + Time(10, 0, 0) });
    Set(gblFormOpen, true);
    Reset(cmpEventForm1)

Use it as a picker

Bind to something read-only and let OnSelectEvent set a variable. The calendar has no opinion about what a tap means.

Mon
3
Weekly triage
09:30 · Reviews
Tue
4
Vendor review
14:00 · Reviews
Wed
5
Site visit — Riverside
All day · Site visits
Fri
7
Grant application deadline
All day · Deadlines
OnSelectEvent: |-
    =Set(
        gblPicked,
        LookUp(colWindow,
            OccurrenceKey = cmpCalendarPro1.SelectedEventKey)
    )

SharePoint

Two lists. Series holds the rules; Occurrences holds the rows this component reads.

Occurrences columnTypeNotes
OccurrenceKeyText, indexedSeriesKey plus yyyymmdd, so a regeneration upserts
SeriesKeyTextBlank for a one off
OccurrenceDateDate, indexedThe column you filter on
StartClockText"09:30", not a datetime. See the contract for why
IsAllDayYes/No
TitleText
ChannelKeyText
ExceptionTypeChoiceNone, Modified, Cancelled

Index OccurrenceDate. A Flow materialises a rolling window of occurrences from the series rules, and ExceptionType protects rows a user has edited from being regenerated over.

The full model, including why the clock is stored as text and what the three edit scopes cost you as writes, is in the recurrence contract.


After you paste

Set Width by hand. A pasted instance arrives at 600 regardless of the YAML. Height comes through intact.

Pass every Config key, including the ones left at their defaults. A Record input's Default does not reach a pasted instance.

The instance syntax is Control: CanvasComponent with a ComponentName sibling, not Control: cmpCalendarPro.

Bind Events to a windowed collection, not to a list. Binding a whole SharePoint list directly will appear to work on a small list and quietly truncate on a large one.

Get new components and templates when they drop

One email when something new ships. Unsubscribe anytime.

Community

Use the toolbar to format · or type markdown directly