
Date Calendar: Unified Date & Time Picker for Fieldhub ERP
Fieldhub is an ERP platform where dates and times are everywhere: deadlines, appointments, filters, and reporting windows all depend on getting a moment in time right. Before this project, that need was met with a patchwork of inputs across the product: free-text fields, inconsistent calendar widgets, and one-off time selectors that didn't share a visual language or a set of rules. I designed a single, configurable Date Calendar component that could absorb all of those use cases: single date, date range, time, time range, and combined date-and-time into one consistent pattern, backed by a color system built to scale across the rest of the product.
Company:
Field Hub
Role:
Senior Product Designer
Scope:
Component design, token architecture
Problem

Variants definition
I started by mapping every temporal input the product actually needed, then grouped them into two families that share one interaction shell:
Date picker
Selection of a single date, a single month, a single year, or a date range, with an optional time component and optional min/max limits.

Time picker
Selection of an hour, a minute, or a full time range, also with optional min/max limits.

Rather than building five or six separate components, I designed one trigger-and-popover shell that reconfigures its internal grid (day, month, or year) and its footer controls (Apply, Cancel, clear, presets) depending on which variant is active. That meant every variant inherited the same header navigation, the same footer button placement, and the same input-masking behavior in the trigger field, so switching between "pick a date" and "pick a date range with time" never felt like switching components.


Presets and ranges
For range selection, I added a presets sidebar :Today, Yesterday, Last Month, Current Week, Previous Week, Current Month, Previous Month, Q1/Q2, Current Year, so users reporting on a fixed window don't need to manually click through a calendar grid to get there.
This paired with a dual-calendar layout for range selection, and with masked start/end inputs so a range could also be typed directly.

Anatomy and states
Because this component would be reused across dozens of contexts, I broke it down to its smallest reusable parts: the trigger input (calendar icon plus masked value), header navigation (month/year chevrons and quick-select chips), the day/month/year grids, the hour and minute lists, the dual time-range inputs, and the shared footer actions. This breakdown also kept the Figma file itself lean — instead of dozens of near-duplicate frames for every configuration, each piece exists once and gets reused across variants, which cut down on component bloat and made the file lighter and faster to work in. Documenting the anatomy this way meant engineering could compose new configurations from existing pieces instead of requesting a new one-off screen each time a new use case came up.


Every interactive element needed a full state set, not just a default appearance. For the day cell alone, I defined default, hover, selected, disabled, and today — each visually distinct enough to scan at a glance, but built from the same token set so they'd stay in sync if the palette ever shifted.
Building the color system underneath it
The states above only work if the underlying color system is disciplined, so alongside the component I built a token architecture with three layers: a global palette (the raw color ramps — neutrals, brand blues, critical/warning oranges — 324 values in total), an alias layer that gives those raw values semantic names like surface/base, surface/action/primary, and surface/action/warning (38 tokens), and a semantic layer on top of that for component-specific consumption (29 tokens), plus a dedicated breakpoints set for responsive behavior.
The alias layer is where the calendar's states actually live: surface/base maps default, hover, active, and selected day cells to neutral/base, neutral/slight, neutral/pale, and neutral/medium; surface/action/primary maps the selected-date and interactive-button states to a ramp of brand blues (brand/70 default, brand/60 hover, brand/80 active, brand/50 for a selected-hover combination); and surface/action/warning does the same with a critical/orange ramp for destructive or warning states elsewhere in the product. Because every state pulls from this alias layer instead of a hardcoded hex value, the calendar's hover, active, selected, and disabled states stay visually consistent with every other interactive component in the system — and the whole set is ready to retheme for dark mode without touching component specs.

Outcome
The result is one component that covers single-date, ranged, timed, and combined date-time selection across Fieldhub, replacing what had been several inconsistent patterns with a single configurable one. Because it's built on the alias token layer rather than one-off styling, any future palette or theme change propagates through the calendar automatically instead of requiring a redesign.
Reflection
The hardest part of this project wasn't designing any individual component — it was building a consistent system of states and interactions that would hold up across every variant, rather than solving each one in isolation. Unifying the color tokens with the rest of the system's existing states, and reducing the overall number of one-off styles in the process, was the core of what made this an optimization rather than just another component. That reduction isn't only a design win. Fewer, shared styles mean less redundant frontend code to ship, which translates directly into a lighter, faster-loading application.

