Tutorials/Power Apps/Power Apps Calendar: A DIY Approach to Date Grids
Power Appsintermediate

Power Apps Calendar: A DIY Approach to Date Grids

Construct a full-month calendar view using galleries and formula logic—ready for scheduling, event tracking, or attendance apps.

NA
Narmer Abader
@narmer · Published June 3, 2026

Building a custom calendar grid is one of those projects that teaches you how Power Apps really works under the hood. Instead of relying on the out-of-the-box calendar screen, you gain control over every pixel of the date grid, navigation logic, and event handling. In this guide I’ll show you how to create a monthly calendar from scratch — no external components, no complex configuration — just galleries and Power Fx.

Once you’ve mastered the grid, you can extend it to show approvals, deadlines, or even team availability. Let’s start with a concrete scenario.

Example Scenario

Imagine you are building an Employee Leave Calendar for a small team. Each month managers need a quick view of who is on leave and which days are public holidays. The calendar must:

  • Display all days of the current month in a grid, with Sunday as the first column.
  • Show the name of the month and the year.
  • Allow navigation to previous/next months.
  • Highlight today’s date.
  • Prepare for future integration with a SharePoint list named LeaveRecords (columns: Employee, Date, Status).

In this first part we focus only on the month grid itself. Event data handling will follow in a separate article.

Setting Up the Month Grid

Start with a blank canvas in Power Apps (tablet or phone). I’ll assume you know how to insert controls and write Power Fx.

1. Store the “Viewing Month”

Place a button named btn_Today somewhere on the screen (later you can move it). Give it the text "Today". This button will reset the calendar to the current month.

Set its OnSelect to:

powerfxbtn_Today OnSelect
Set(varViewMonth, Date(Year(Today()), Month(Today()), 1))

We also need this variable to be set when the screen loads. Go to the Screen’s OnVisible property and enter the same code:

powerfxScreen OnVisible
Set(varViewMonth, Date(Year(Today()), Month(Today()), 1))

varViewMonth always holds the first day of whatever month the user is looking at.

2. Generate the 42‑day Sequence

A standard month grid covers at most 6 weeks × 7 days = 42 cells. We’ll generate exactly 42 dates starting from the first Sunday before or equal to the first day of the month.

Insert a Vertical Gallery (let’s name it gal_CalendarGrid) and set its Items property:

powerfxgal_CalendarGrid Items
ForAll(
  Sequence(42),
  varViewMonth + Value - Weekday(varViewMonth, StartOfWeek.Sunday)
)

Each cell gets the correct date for that place in the grid, shifted so the top‑left cell is always a Sunday.

Change these properties on gal_CalendarGrid:

PropertyValue
FillWhite
TemplatePadding0
TemplateSizeSelf.Height / 6
WrapCount7

Without WrapCount = 7 the dates would appear in a single column. Now the gallery wraps after every 7 items, creating the grid.

4. Show the Day Number

Inside the gallery template, delete any existing label and insert a new Button named btn_DayNumber. Set its Text to:

powerfxbtn_DayNumber Text
Day(ThisItem.Value)

Style the button so it looks like a calendar cell:

powerfxbtn_DayNumber style properties
// Border properties
BorderColor: RGBA(179, 179, 179, 1)
BorderThickness: 0.5

// Shape – circular for date appearance
RadiusBottom: 180
RadiusTop: Self.RadiusBottom
RadiusLeft: Self.RadiusBottom
RadiusRight: Self.RadiusBottom

// Size
Height: 40
Width: 40

// Colors
Color: If(
  IsToday(ThisItem.Value), White,
  Date(Year(ThisItem.Value), Month(ThisItem.Value), 1) = varViewMonth, Black,
  LightGray
)
Fill: If(IsToday(ThisItem.Value), ColorValue("#0063B1"), Transparent)

// Hover feedback
HoverFill: ColorValue("#0063B120")
PressedFill: ColorValue("#0063B140")

The Color formula makes:

  • Today’s number white on a blue circle.
  • Dates that belong to the current month black.
  • Dates of adjacent months light gray.

5. Add Month/Year Header

Above the grid, add a Label named lbl_MonthYear. Set its Text to:

powerfxlbl_MonthYear Text
Text(varViewMonth, "[$-en-US]mmmm yyyy")

Make the font size 28, bold, and pick a color that matches your app theme.

6. Insert Weekday Headers

Add a new Horizontal Gallery above gal_CalendarGrid named gal_Weekdays. Set its Items to:

powerfxgal_Weekdays Items
Calendar.WeekdaysShort()

Configure the gallery layout:

PropertyValue
Height45
TemplatePadding0
TemplateSizeSelf.Width / 7
ShowScrollbarfalse

Position it directly above the calendar grid (X and Y aligned). For each label inside this gallery, style it:

powerfxWeekday label style
Color: White
Height: Parent.TemplateHeight
Text: ThisItem.Value
Width: Parent.TemplateWidth
Fill: ColorValue("#0063B1")   // solid header background

The weekdays now sit above each column, acting as a table header.

Allow users to browse months.

Previous Month

Insert a ChevronLeft icon (or a left arrow) to the left of the btn_Today. Set its OnSelect:

powerfxChevronLeft OnSelect
Set(
  varViewMonth,
  Date(Year(varViewMonth), Month(varViewMonth) - 1, 1)
)

Next Month

Insert a ChevronRight icon to the right. OnSelect:

powerfxChevronRight OnSelect
Set(
  varViewMonth,
  Date(Year(varViewMonth), Month(varViewMonth) + 1, 1)
)

Test the calendar: pressing the arrows should move the month forward/back while keeping the grid in sync.

Click‑to‑Navigate from Adjacent Months

A nice behaviour is to jump to a different month when the user taps on a date that belongs to the previous or next month (as seen in many desktop calendars). Inside the btn_DayNumber button, add this OnSelect code:

powerfxbtn_DayNumber OnSelect (optional)
Set(
  varViewMonth,
  Date(Year(ThisItem.Value), Month(ThisItem.Value), 1)
)

Now clicking a gray date switches the calendar to that month.

Finishing Touches

  1. Background image – Place an image behind all controls and set its ImagePosition to Fit or Tile. This gives the app a polished look.

  2. Dark overlay – Insert a rectangle with Fill = RGBA(0,0,0,0.3) behind the calendar controls to make text more readable over a busy background.

  3. Theme colors – Change the blue highlights to whatever matches your brand. All the formulas use ColorValue("#0063B1") once, so you can replace it with a variable or theme colour.

Performance & Delegation Notes

  • The Sequence(42) and ForAll run entirely on the client – there is no delegation issue.
  • If you later connect to a SharePoint list for events, remember that Filter against large datasets requires delegation‑friendly operators (e.g., Date >= ... && Date < ...). Always pre‑filter by month range to avoid hitting the delegation limit.
  • Gallery template sizes should be calculated (e.g., Self.Height / 6) rather than hard‑coded so the layout adapts to different screen sizes.

Common Mistakes & Troubleshooting

MistakeSymptomFix
Forgetting WrapCount = 7Dates appear in a single column.Set gallery WrapCount to 7.
Not resetting varViewMonth on OnVisibleCalendar shows an unexpected month when app starts.Add the Set(...) code to the screen’s OnVisible.
Using StartOfWeek.Monday for grid startGrid starts on Monday instead of Sunday (if desired).Use StartOfWeek.Sunday to keep Sunday first.
Hard‑coded TemplateSizeGrid cells don’t resize on different screen heights.Use Self.Height / 6 or Self.Height / 7 depending on layout.
Button for day number does not have transparent fill for non‑today cellsGray background or unwanted highlight.Ensure Fill = If(IsToday(...), ColorValue("#0063B1"), Transparent) and HoverFill / PressedFill use alpha colours.

Where to Go Next

With the grid and navigation working, you’re ready to pull events from your data source and display them in each cell. That will be the subject of the next guide – we’ll populate the calendar with records from the LeaveRecords list, show employee names on each day, and allow managers to add new entries.

In the meantime, experiment with the grid styling: change the radius, add a subtle shadow, or animate the month‑year header. The more you tweak, the better you’ll understand the galleries.


References