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
ComponentsDeadline

Deadline

A due date that knows about weekends and observed holidays. Give it a start date and a number of days; it returns the date the clock actually runs out, the working days left, and a sentence explaining how it got there. It computes and reports — it writes nothing.

cmpDeadline.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

DueOn track
Tue, Sep 15, 2026
19 working days left
30 working days from Aug 3 lands on Sep 15 — 13 days skipped (1 holiday).
19
Work days
13
Skipped
1
Holidays

Inputs

CountMode
Accent

Push the start into November and watch Thanksgiving and Veterans Day fall inside the window — the due date moves two extra days.

A due date that knows about weekends, holidays, and the difference between them.

Give it a start date and a number of days. It returns the date the clock actually runs out, how many working days are left, and a sentence explaining how it got there. It renders a card, and it exposes every number it computed so you can draw your own.

It does not write anything. No status column, no stored due date, no reminder. It computes and reports; what that means is yours.


Why not just use DateAdd

DateAdd(start, 30, TimeUnit.Days) is wrong for most statutory and contractual clocks, and the three reasons stack up.

Weekends do not count. Thirty working days from 3 August is 14 September, not 2 September.

Holidays do not count either, so the answer depends on which months the window crosses. A thirty day clock starting in October crosses three federal holidays; the same clock starting in February crosses one. Same allowance, different date.

And a holiday is observed, not celebrated. Independence Day on a Saturday is observed on the Friday. The office is closed on the third, so the third is the day that does not count. An app that skips the fourth tells someone the office is open when it is shut.

The gap grows with the window. At thirty days it is usually about twelve. At a hundred and five working days from 17 August 2026 the naive answer is 30 November and the real one is 20 January, fifty one days later. Every one of them is a day somebody thought they had.


Properties

Input

PropertyTypeDefaultDescription
StartDateDateAndTimeToday()The event the clock runs from. The start date itself is never counted, so day one is the next working day
DaysNumber30How many days the clock allows. Capped at 400 internally
CompletedDateDateAndTimeblankBlank while open. Set it and the status reads Complete and the countdown stops
LabelText"Due"What the deadline is for, shown above the date
HolidaysTableone sentinel rowHolidayName and HolidayDate, where the date is the observed date. Leave it and US federal holidays are used
ConfigRecordsee belowBehaviour and look
ThemeTableDark and LightOne row per mode

Config

KeyDefaultDescription
CountMode"business"business or calendar
WorkDays"1,2,3,4,5"Day indexes, Sunday is 0. A Sunday to Thursday week is "0,1,2,3,4"
DueSoonDays3Working days remaining at which the status turns amber
ShowBreakdowntrueThe sentence explaining the date, and the rule above it
ShowStatstrueThe three tiles at the bottom
ShowProgresstrueThe elapsed time bar
CompactfalseLabel, pill and date only. No countdown, breakdown, bar or tiles
DarkModefalsePicks a row of the Theme table
Accent""Hex string. Blank uses the theme accent
Radius12Corner radius

Card height is 236 expanded and 92 compact. The component sets it from Compact, so leave Height alone unless you are hiding sections individually.

Output

PropertyTypeDescription
DueDateDateAndTimeThe answer
StatusKeyTextdone, overdue, due-today, due-soon, on-track. Branch on this, not on the label
StatusLabelTextThe same thing in words, in whichever unit the mode counts
IsOverdueBooleanPast due and not completed
DaysRemainingNumberCalendar days, negative when overdue
WorkDaysRemainingNumberWorking days. This is the number people plan against
SkippedDaysNumberNon working days inside the window. Zero in calendar mode
SkippedHolidaysNumberObserved holidays inside the window, in either mode
NextWorkDayDateAndTimeThe next working day after today
BreakdownTextThe sentence that explains the date
FederalHolidaysTableThe built in table, so you can join your own closures to it

Events

EventDescription
OnSelectThe card was tapped

What the card shows

Label and status pill across the top. The pill is a coloured dot and a word, not colour alone, so the state survives being printed and being read by somebody who cannot separate the hues.

The date, large, as Wed, Jan 20, 2027.

The countdown, in the unit the mode is counting: working days in business mode, calendar days in calendar mode. Overdue is always calendar days in both, because how late something is gets counted the way a person counts it.

The breakdown sentence. 105 working days from Aug 17 lands on Jan 20. 51 days skipped (7 holidays). This is the part that stops somebody rebuilding the calculation in a spreadsheet.

A progress bar, elapsed time over the whole span. Empty before the clock starts, full once it is overdue or complete.

Three tiles for the numbers the sentence refers to: work days remaining, skipped, holidays. A number somebody can point at settles an argument faster than a paragraph does.


Implementation details

No state at all. Every output derives from the inputs, so OnReset does nothing and the component draws correctly the moment it is pasted. There is no load step and no host wiring beyond passing the inputs.

The search is bounded. Adding N working days generates a window of candidate dates, keeps the working ones, and takes the Nth. The window is Days * 2 + 14, which is always enough because a five day week needs about 1.4 times the target and the extra fortnight covers a run of closures. Days is capped at 400, since an unbounded search is a hang rather than an error, and working day precision on a date two years out is false precision anyway.

The holiday table covers three years, the year of StartDate and the two either side, so a window crossing New Year still finds January's holidays. A 105 day clock from August reaches New Year's Day and MLK Day of the following year; a two year table would come back two days early and say nothing about why.

The observed rule is applied to the five fixed date holidays and the nth weekday computed for the rest. Independence Day 2026 falls on a Saturday, so the table carries Friday 3 July.

The progress bar measures elapsed over span, not remaining over allowance. The second one silently assumes the clock started today, and a start date three months out makes the fraction negative.

WorkDaysRemaining is not DaysRemaining. Three calendar days over a long weekend is zero working days. Showing the calendar count is how a deadline gets missed by somebody who was watching the countdown.

The working week is configurable. Sunday to Thursday is the working week across much of the Gulf. Hard coding Saturday and Sunday is what stops a component being usable outside the US, and it costs one Config key to avoid.

An empty holiday table is a sentinel, not Table(). An empty table literal has no columns, so anything reading HolidayDate off it fails to compile. The default carries one row dated 1900, and rows dated 1900 are treated as absent.


Use cases

SituationHow it is set up
Thirty days to respond to a noticeDays: 30, business mode, default holidays
Five business days to cure a deficiencyDays: 5, DueSoonDays: 2, compact
Ninety calendar days to close out an awardCountMode: "calendar"
Materials due ten days before a panelStartDate is the panel date minus the window, or compute backwards in the host
SLA clock on a support ticketDays: 2, DueSoonDays: 1, compact in the list
Recertification due annuallyDays: 365, calendar mode
A Gulf region deploymentWorkDays: "0,1,2,3,4"
Agency shutdown weekPass your closures joined to FederalHolidays

When not to use it. If the clock runs in hours rather than days, or if the deadline is a fixed date somebody typed in, this is the wrong tool. It answers one question, and it is only interesting when the answer is not obvious.


Examples

In a list, one compact card per row

Compact mode is the one for a gallery — a single row, no breakdown. The detail is for a detail screen.

Due
Mon, Aug 10, 2026
Overdue
Label:  =ThisItem.Title
StartDate: =ThisItem.AwardDate
Days:   =ThisItem.DaysAllowed
Height: =92
Config: |-
    ={
        CountMode: "business",
        DueSoonDays: 3,
        ShowBreakdown: false,
        ShowStats: false,
        ShowProgress: false,
        Compact: true,
        DarkMode: gblDarkMode,
        Accent: "", Radius: 10
    }

Add your own closures

Join your closures to FederalHolidays rather than restating them, so the two can't drift apart.

DueOn track
Mon, Dec 7, 2026
75 working days left
75
Work
7
Skip
1
Hol
Holidays: =Table(
    { HolidayName: "Agency closure",
      HolidayDate: Date(2026, 12, 24) },
    { HolidayName: "Agency closure",
      HolidayDate: Date(2026, 12, 26) }
) & cmpDeadline1.FederalHolidays

Store the due date on save

Store it, don't compute it on read — a later holiday-table fix shouldn't move a date someone was already given.

DueOn track
Tue, Sep 15, 2026
19 working days left
19
Work
13
Skip
1
Hol
Patch(
    'Requests',
    LookUp('Requests', ID = gblRequestId),
    { DueDate: cmpDeadline1.DueDate }
)

SharePoint

ColumnTypeNotes
StartDateDateThe event the clock runs from
DaysAllowedNumber
DueDateDate, indexedWritten once, then filterable
CompletedDateDateBlank while open

Index DueDate. Filtering on a stored indexed date between two values is delegable at any list size; anything computed at render time is capped at your delegation limit and fails silently past it.

Recompute the stored date deliberately, in a Flow, when StartDate or DaysAllowed changes. Recomputing on every read means a holiday table correction quietly moves dates people are working to.


After you paste

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

Pass every Config key, even the ones you are leaving at their defaults. A Record input's Default does not reach a pasted instance, so the component Coalesces each key internally, and passing the full record is what a real host should look like.

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


Try this

Set the start to 17 August 2026 with 105 days in working mode. The card reads Wed, Jan 20, 2027, 51 days skipped, 7 holidays, and the comparison panel shows DateAdd fifty one days short.

Switch to calendar days. The date moves back to 30 November, skipped drops to zero, and the holiday count drops to four, because the shorter window misses Christmas, New Year and MLK Day.

Pull the start back to 2 July and Independence Day appears in the list as Friday 3 July, not the fourth. That is the observed rule, and it is the detail most implementations get wrong.

To see the working week matter, use 26 July 2026 with 10 days. Monday to Friday gives Friday 7 August; Sunday to Thursday gives Sunday 9 August. Most starts give the same answer either way, since both weeks have five working days, so pick a start that lands on a weekend to see them separate.

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