East Blue
KeepReady
Date Picker - Header Trigger Component link

The month and year chips in the calendar header. Tapping one switches the calendar to its month or year view. Six versions — three states, with or without a caret.

Keep — one State setting, and the caret it was missing
All four DS Health traits pass. Two independent booleans became a single State setting, matching the field trigger and the naming guidelines. A hasCaret option adds the disclosure indicator that was missing — without it the chips read as static labels rather than controls that open a view. It is badged Needs Refinement for one reason: at 24px tall the chip is well under the minimum touch target.
In Context

Two instances sit between the chevrons in the calendar header — one for the month, one for the year. Tapping either switches Date Picker - Calendar into its Month or Year mode, where the chip is replaced by a static title and a back chevron.

Live Preview
Month
Properties
State
hasCaret
Content
#text
DS Health
Reusable
Pass
The same chip serves both the month and the year position; only its text differs. hasCaret lets it be used where a disclosure indicator would be wrong.
Self-contained
Pass
Carries its own surface, radius, type style, all three states, and the caret icon instance.
Consistent
Pass
Uses State like Date Picker does, and wraps in a Container like every other component in the family.
Composable
Pass
Instanced twice inside the calendar header's Container, between the two chevrons.
Behavior
State iOS Android Figma Property Notes
State=Default N/A N/A #F6F9FD Resting chip. Both header instances use this.
State=Pressed N/A N/A #EEF2F9 Momentary. Not used to mark which view is open.
State=Disabled N/A N/A #FFFFFF Surface stays, text and caret mute together.
hasCaret=true N/A N/A Chevron Down 16px icon instance. Widens the chip from 57 to 81.
Issues
  • The 24px chip is deliberate. The calendar header is a fixed strip, and a taller chip would push the grid down. The drawn chip stays 24px while the tap target is expanded natively to 44 pt on iOS and 48 dp on Android, which the Accessibility table sets out for both platforms. Confirmed with design — the same reasoning that settled the 32 × 32 cell. Growing the drawn chip is logged as a recommendation for a future redesign. C5 · Interaction State Coverage
  • Two booleans became one State setting. isDisabled and isPressed sat side by side, which allowed a pressed-and-disabled combination that means nothing. They are now State = Default | Pressed | Disabled — the shape the naming guidelines ask for, and the one Date Picker already used. C2 · Variant & Property Naming
  • The setting with one value is gone. A Kind setting existed with Month as its only value — a dropdown with nothing to choose, and no matching Year. It was dropped: the same chip serves both positions, and only its text differs. C2 · Variant & Property Naming
  • The chip now says it opens something. It was a filled rectangle with a bold label and no disclosure indicator, which reads as a static chip. hasCaret adds a Chevron Down icon instance after the text — the same signal the field trigger's dropdown carries. The caret mutes along with the label in Disabled. C5 · Interaction State Coverage
  • The wrapper matches the family. The inner frame was Label Container, spaced Title Case. It is now Container, like the cell and the weekday header. C1 · Layer Structure & Naming
  • The header no longer uses Pressed to mean selected. In the calendar's Day mode the month chip shipped in its Pressed version while the year chip sat at Default, which read as "this one is active". Both are Default now — pressed is a momentary state, not a way to mark the open view. C5 · Interaction State Coverage
Recommendations
  • Give the chip a taller tap area. The drawn chip is 24px against 44 on iOS and 48 on Android — shorter even than the 32px day cell. The target is expanded natively today, which is the accepted trade for now, but an expanded target the user cannot see still misleads: two chips sit 8px apart while both claim 44. Worth growing the drawn chip whenever the calendar header is next reworked. Not a blocker for this release. A11y
  • Announce the chip as a button that opens a picker. v1.1: Applied — the Accessibility table now carries a Role / trait row (.accessibilityAddTraits(.isButton) · Modifier.semantics { role = Role.Button }) alongside a label row that names the value and the action together, "August, select month" rather than "August". Both platforms answered. A11y
  • Rename the component to Date Picker - Header Trigger in Figma. v1.1: Applied — node 6779:105937 now reads Date Picker - Header Trigger, so the chip groups with Cell, Header, Calendar and the picker itself in the assets panel. The recommendation described it as still named Header Trigger; that has not been true since the rename. Rename
States
Header Trigger
Label
Properties
State
hasCaret
Label
Properties
State Default
hasCaret true
Label Label
Versions 6
Colors
Container surface #F6F9FD
#text #0A2757
Chevron Down #445C85
Typography
#text Primary/Label/Base
Layout
Height Hug (24px)
Width Hug (81px)
Radius 4px
Padding H 8px
Padding V 4px
Gap 8px
Alignment Center
Colors by State

Three states, six versions. The caret is a stroke, not a fill, which is why it carries border tokens rather than icon ones. Disabled swaps the surface to white and mutes the label and caret to the same value from two different tokens.

Role Token DefaultPressedDisabled
Container surface bg/color-bg · pressed bg/color-bg-strong · disabled bg/color-bg-primary-inverse #F6F9FD #EEF2F9 #FFFFFF
#text text/color-text · disabled text/color-text-disabled #0A2757 #0A2757 #C2CFE5
Chevron Down border/color-border-strongest · disabled border/color-border-disabled #445C85 #445C85 #C2CFE5
Installation Planned API

iOS — Swift Package Manager

.package(url: "https://github.com/AY-Org/eb-ds-ios", from: "1.0.0")

Android — Gradle (Kotlin DSL)

implementation("com.eastblue.ds:date-picker:1.0.0")

Import

import EastBlueDS
import com.eastblue.ds.datepicker.*

Planned API — the native library does not exist yet. The artifact is the Date Picker family, not this component: Cell, Header, Header Trigger, Calendar and the picker itself all ship in <code>com.eastblue.ds:date-picker</code> and import <code>com.eastblue.ds.datepicker.*</code>.

Property Mapping

Figma properties mapped to the intended native parameters, in the order the Figma property panel lists them. State is the one property that is not a single parameter: Default and Disabled are a flag, while Pressed is what the platform reports while a finger is down.

Figma PropertySwiftUICompose
State — Default, Pressed, Disabled isDisabled: Bool = false — Pressed is the momentary press state, not a parameter enabled: Boolean = true — Pressed comes from the InteractionSource
hasCaret — true, false hasCaret: Bool = true hasCaret: Boolean = true
Label (text) label: String label: String
Usage Snippets Planned API
Header Trigger — a month or year chip
EBDatePickerHeaderTrigger(
    label: "Label",
    hasCaret: true
)
EBDatePickerHeaderTrigger(
    label = "Label",
    hasCaret = true
)
Accessibility
RequirementiOSAndroid
Label Button with .accessibilityLabel("August, select month") Modifier.clickable(onClickLabel = "Select month")
Role / trait .accessibilityAddTraits(.isButton) Modifier.semantics { role = Role.Button }
Minimum target .frame(minHeight: 44) around the 24pt chip Modifier.minimumInteractiveComponentSize() — 48dp
Dynamic type Supported, scales to AX5 — the chip hugs, so width grows with the label sp units, scales with the system font scale
Caret is decorative .accessibilityHidden(true) on the chevron contentDescription = null
Usage Guidelines

Do

Turn the caret on wherever the chip opens a view.

Don't

Don't ship a bare chip that looks identical to a static label.

Do

Keep both chips in Default while the calendar is on the day view.

Don't

Don't use Pressed to mark which view is open — that's a selection meaning on a momentary state.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Ready Container → #text plus an optional icon instance.
C2 Variant & Property Naming Ready State replaced two booleans; hasCaret follows the boolean prefix convention with lowercase values.
C3 Token Coverage Ready Three surfaces and two text colours, all standard tokens.
C4 Native Mappability Ready A labelled button with an optional trailing icon.
C5 Interaction State Coverage Ready All three states are built across both caret options, and there is no Focused state by design — these are mobile components. The 24px chip is a deliberate visual size; the tap target is expanded natively to 44 pt / 48 dp, as the Accessibility table sets out.
C6 Asset & Icon Quality Ready The caret is a Chevron Down icon instance that recolours per state.
Variants Inventory (6 total)

3 State × 2 hasCaret = 6 variants — the matrix is complete, every combination is built.

StatehasCaretSurfaceWidthNode
Defaultfalse#F6F9FD576493:75116
Pressedfalse#EEF2F9576493:73968
Disabledfalse#FFFFFF576493:73974
Defaulttrue#F6F9FD817409:160301
Pressedtrue#EEF2F9817409:160304
Disabledtrue#FFFFFF817409:160307
1.1.0 — September 2026Minor
Renamed to the family, Style and Code tabs rebuilt — node 6779:105937
The component has its family name. The August assessment recorded it as Header Trigger and recommended the Date Picker - prefix. Node 6779:105937 now reads Date Picker - Header Trigger, so the chip groups with Cell, Header, Calendar and the picker in the assets panel. This is what makes the release a minor rather than a patch.
C2 resolved
The 24px chip is a decision, not a gap. The calendar header is a fixed strip and a taller chip would push the grid down, so the drawn chip stays 24px while the tap target expands natively to 44 pt / 48 dp. Same reasoning that settled the 32 × 32 cell. C5 moves to Ready; growing the drawn chip stays on the list as a recommendation for a future redesign.
C5 resolved
The chip announces itself as a button. The recommendation asked for a button role and a label naming both the value and the action. Accessibility now carries a Role / trait row and a label row reading "August, select month" rather than "August", answered for iOS and Android.
A11y
The documented type style did not exist. Typography read Primary/Bold/Subheading, which is not a style in the database. The layer resolves to Primary/Label/Base. The Font row spelling out Proxima Soft Bold · 16 / 16 · +0.25 is gone — that lives in the text style.
C3 resolved
The caret had no documented colour. Two of the three roles were on the page and the chevron was on none of them. It is a stroke, not a fill, which is why it carries border/color-border-strongest and border/color-border-disabled rather than an icon token. A Colors by State table now covers all three roles across all three states.
C3 resolved
The surface tokens named the wrong steps. They read bg/color-bg-subtle, bg/color-bg-subtle-pressed and bg/color-bg-main; the bindings are bg/color-bg, bg/color-bg-strong and bg/color-bg-primary-inverse. The hex values were right throughout — only the token paths were wrong, which is the worse half to get wrong.
C3 resolved
The preview rendered in the wrong typeface. .eb-preview-dphdr declared no font, so it inherited the documentation font — BarkAda — through .eb-preview-scope and body, while the component is Proxima Soft Bold. Proxima Soft was loaded the whole time; the preview simply never asked for it.
Docs
The caret drew in the label colour. It inherited currentColor, so Default and Pressed rendered #0A2757 instead of #445C85. Disabled looked correct only by coincidence — the text and border disabled tokens both land on #C2CFE5.
Docs
Gap was documented as 4px; the panel says 8. The auto-layout panel confirms 8, and the arithmetic agrees: 8 + 41 + 8 + 16 + 8 reproduces the 81px caret width exactly. The caret path and stroke-width were redrawn from Figma’s own M4.5 6.5L8 10L11.5 6.5 at 2, replacing an approximation at 1.6.
Docs
Layout was not on the seven-key list. It carried Corner radius, Gap to caret, Caret and Touch target while missing Padding V and Alignment. Now Height · Width · Radius · Padding H · Padding V · Gap · Alignment, each read off the auto-layout panel, with Width switching to Hug (57px) when the caret is off.
Docs
The install block pointed at coordinates that will never exist. gcash/east-blue-ios and com.gcash.eastblue:components:1.0.0, with no Import line at all. Under the family rule the artifact is com.eastblue.ds:date-picker — the whole Date Picker family, not this component — imported as com.eastblue.ds.datepicker.*.
Docs
Usage Snippets documented the header, not the chip. They showed HStack(spacing: 4) and Row(horizontalArrangement = …) assembling two triggers — how to draw a header, not how to use this component. One snippet per driving value now, built from the same definition as the spec card and the live preview.
Docs
The component had two names and a parameter that traced to nothing. Spec cards said EBPickerHeaderTrigger, and the mapping offered showsCaret for a property Figma calls hasCaret. All surfaces now read EBDatePickerHeaderTrigger with hasCaret and label, each tracing 1:1 to a property in the panel.
Docs
Property Mapping named a layer where a property belongs. The third row read #text; the Figma property is Label. Rows are now prose grouped by property with their values listed, and the Variants Inventory gained the node ID for each of the six versions.
Docs
Code Connect was populated on a component with nothing registered. Three rows claimed readiness against a native library that does not exist. The section is gone; C7 stays Not Mapped.
Docs
1.0.0 — August 2026Initial
First assessment · node 6779:105937
C2 — isDisabled and isPressed collapsed into State. Interaction states belong on one setting, not on parallel booleans that permit combinations with no meaning.
C2 resolved
C2 — the single-value Kind setting removed. It offered only Month, with no Year counterpart.
C2 resolved
C5 — hasCaret added. A Chevron Down instance now signals that the chip opens a view; it mutes with the label in Disabled.
C5 resolved
C1 — Label Container renamed to Container, matching the rest of the family.
C1 resolved
C5 — the calendar header stopped using Pressed to mean selected. Both chips now render Default in Day mode.
C5 resolved
C5 — tap area unchanged at 24px against 44/48 minimums.
C5 open