Date Picker
Choose a calendar date in a compact popover.

use blinc_cn as cn;
use blinc_core::reactive::{Signal, computed};
use blinc_layout::{binding::IntoReactive, prelude::*};
pub fn date_picker_demo(date: Signal<Option<cn::CalendarDay>>, disabled: Signal<bool>) -> Div {
div()
.class("demo-stack")
.child(cn::label("Appointment date"))
.child(
cn::date_picker(date)
.today(cn::CalendarDay::new(2026, 11, 4))
.disabled(disabled),
)
.child(
bound_text(computed(move |g| {
g.get(date)
.flatten()
.map(|day| format!("Selected: {:04}-{:02}-{:02}", day.year, day.month, day.day))
.unwrap_or_else(|| "No date selected".into())
}))
.class("demo-caption"),
)
}
fn bound_text(value: impl IntoReactive<String>) -> Text {
Text::bound(value.into_reactive())
}
@layer components {
.cn-date-picker-trigger {
height: 40px;
min-width: 180px;
gap: 8px;
padding: 0 12px;
font-family: var(--font-sans);
font-size: 14px;
color: var(--text-primary);
background: var(--cn-date-picker-bg, var(--input-bg));
border: 1px solid var(--cn-date-picker-border, var(--border));
border-radius: var(--cn-date-picker-radius, var(--radius-md));
cursor: pointer;
transition: background var(--duration-fast) var(--ease-state), border-color var(--duration-fast) var(--ease-state);
}
.cn-date-picker-trigger[data-size="sm"] {
height: 32px;
font-size: 12px;
}
.cn-date-picker-trigger[data-size="lg"] {
height: 48px;
font-size: 16px;
}
.cn-date-picker-trigger[data-empty],
.cn-date-picker-icon {
color: var(--text-secondary);
}
.cn-date-picker-trigger:hover {
background: var(--surface-overlay);
}
.cn-date-picker-trigger:focus-visible {
outline: 2px solid var(--focus-ring);
outline-offset: 2px;
}
.cn-date-picker-trigger:disabled {
opacity: 0.5;
cursor: not-allowed;
background: var(--input-bg);
}
.cn-date-picker-content {
padding: 12px;
gap: 8px;
}
.cn-date-picker-content .cn-calendar {
padding: 0;
border: 0;
background: transparent;
}
.cn-date-picker-clear {
padding: 6px 10px;
border-radius: var(--radius-sm);
color: var(--text-secondary);
cursor: pointer;
font-size: 13px;
transition: background var(--duration-fast) var(--ease-state);
}
.cn-date-picker-clear:hover {
background: var(--surface-overlay);
color: var(--text-primary);
}
.cn-date-picker-clear:focus-visible {
outline: 2px solid var(--focus-ring);
outline-offset: 1px;
}
.cn-date-picker-clear:disabled {
opacity: 0.5;
cursor: not-allowed;
background: transparent;
}
}
Usage and properties
Choose a calendar date in a compact popover. Apply CSS after the component layer to restyle the documented parts.
Use the installation guide to add blinc_cn and its component stylesheet. Create the fixture bindings once, and return the demo from your UI builder. Values marked Bound accept Signal/Computed sources where the API supports them; structural options configure the component at construction.
| Property | Type | Update model | This example |
|---|---|---|---|
selected | Signal<Option<CalendarDay>> | Bound | 2026-11-04 |
today | CalendarDay | Construction | 2026-11-04 |
disabled | bool or IntoReactive<bool> | Bound | values.disabled |
Keyboard and interaction
Tab reaches the trigger; Enter or Space opens the calendar, which has its own keyboard navigation. Escape or an outside click closes it. :focus-visible marks keyboard focus.
Customizing it
Add application CSS after the default component layer. These selectors are the restyling surface for this component:
.cn-date-picker-trigger.cn-date-picker-icon.cn-date-picker-value.cn-date-picker-content.cn-date-picker-footer.cn-date-picker-clear
Theme and component variables: --primary, --text-primary, --text-secondary, --surface, --border, --radius-default, --duration-fast, --ease-state.
Built-in themes
The Live theme control installs Blinc's own theme bundles, including their colours, focus rings, corner shapes and motion tokens.
pub fn theme_bundle_for(name: &str) -> blinc_theme::ThemeBundle {
match name {
"restrained" => blinc_theme::RestrainedTheme::bundle(),
"expressive" => blinc_theme::ExpressiveTheme::bundle(),
_ => blinc_theme::HybridTheme::bundle(),
}
.with_css(blinc_cn::cn_styles::CN_STYLES)
}Download the default widget and component stylesheets. Sample assets and licenses are available in the asset guide.
Documentation
From the canonical component guide.
cn::calendar is the inline date-selection component. cn::date_picker wraps
that calendar in a popover and shows its selected date in a compact trigger.
It uses the same CalendarDay and Signal<Option<CalendarDay>> model.
Calendar selection uses --cn-calendar-selected-bg (default --primary) and
--cn-calendar-selected-color (default --text-inverse). Event dots and icons
use the selected foreground colour while their day is selected, then return to
application colours. These colours follow the
protected selection rules.
use blinc::cn::prelude::*;
use blinc::core::reactive::signal;
let selected = signal(None::<CalendarDay>);
let disabled = signal(false);
let placeholder = signal("Choose a date".to_owned());
let picker = cn::date_picker(selected)
.placeholder(placeholder)
.disabled(disabled)
.week_start(1)
.format(|day| format!("{:02}/{:02}/{}", day.day, day.month, day.year))
.on_change(|date| tracing::info!(?date, "Date selected"));
The default format is YYYY-MM-DD. Picking a day writes Some(day) and closes
the popup. The clear action writes None; .clearable(false) omits it, and
.clear_text(...) accepts a string, Signal or Computed. External writes update
the trigger and an open calendar without invoking on_change. Choosing the
same date closes the popup without emitting another change. Disabling an open
picker closes it and rejects edits.
Tab reaches the trigger; Enter/Space opens it. The calendar retains its own
month controls and keyboard navigation. Clicking outside dismisses the popup.
size(InputSize), week_start, min_year, max_year, today and events
configure its presentation through the existing calendar API.
| Class | Part |
|---|---|
.cn-date-picker-trigger | Trigger; `data-size="sm |
.cn-date-picker-icon, .cn-date-picker-value | Calendar icon and formatted date/placeholder |
.cn-date-picker-content | Detached popup; also has .cn-popover-content |
.cn-date-picker-footer | Clear-action row |
.cn-date-picker-clear | Clear button; disabled, :hover, :focus-visible |
The calendar keeps its documented .cn-calendar-* part classes. Override
--cn-date-picker-bg, --cn-date-picker-border and --cn-date-picker-radius
or target the part classes. .class(...) and .id(...) apply to the trigger;
the popup lives in the overlay layer, outside the trigger's descendants.
.booking-date { min-width: 220px; }
.cn-date-picker-content { padding: 16px; }
.cn-date-picker-clear { color: var(--primary); }
Platforms and version
The component API is available in Blinc 0.6.0. The Live example runs in a dedicated worker and requires a compatible GPU surface. Preview and Code remain available when Live cannot start. The canvas has a descriptive label; a full screen-reader DOM mirror is not provided. The gallery integration is based on revision e2e55c24e078.
Recordings and live demos use the default Hybrid theme with bundled Noto Sans. The recording uses a 560 × 480 logical viewport at twice that resolution. Live follows its container and actual display density. Source base revision · Exact build source · Artifact versions and checksums · Font license.