Event & Milestone Styles
DayFlow Scheduler includes a powerful, design-system-first styling engine for events. Events can be styled inline using event.style or referenced by key using event.styleId paired with a central styleRegistry.
Every variant and milestone marker below includes a Live Interactive Demo rendered directly via @dayflow-scheduler/core's styling engine and native components.
Event Variants (EventVariant)
The core structure of an event block is controlled by its variant. DayFlow provides 6 foundational variants:
| Variant | Key | Description |
|---|---|---|
| Filled | 'filled' | Solid background fill with optional rounded corners. |
| Bordered | 'bordered' | Solid background fill wrapped in a solid or dashed border stroke. |
| Outlined | 'outlined' | Transparent/light background framed by a distinct border stroke. |
| Line | 'line' | Minimalist horizontal accent bar with customizable title placement. |
| Indented | 'indented' | Left accent bar (pill treatment) with full background fill. |
| Rounded | 'rounded' | Capsule shape with fully rounded ends (border-radius: 9999px). |
Use event.style for the full styling API, or the event.color and event.variant shorthands when only the primary color and structure need to change.
| Event entry | When to use |
|---|---|
event.style | Apply a complete inline EventStyleSpec, including decorations. |
event.color | Change only the event's primary color without creating a style object. |
event.variant | Select a structure alongside event.color or the resource's base color. |
| Common field | Type | Default / behavior |
|---|---|---|
style.variant | EventVariant | Required in event.style; selects one of the six structures above. |
style.color | ColorValue | Primary fill, stroke, or accent color. Accepts a CSS color or { light, dark } theme-aware pair. |
style.textColor | ColorValue | Inferred from the variant unless explicitly set. |
style.opacity | number | Opacity of the complete event visual from 0 to 1; defaults to 1. |
style.borderRadius | number | Corner radius in pixels for block variants; defaults to 12. Line and rounded enforce their own shapes. |
1. Filled Variant
Solid background fill with maximum visual emphasis.
| Field | Default / behavior |
|---|---|
color | Primary fill color; defaults to '#3b82f6'. |
backgroundColor | Overrides the fill without changing color. |
textColor | Defaults to white. |
Filled Variant
09:00 AM to 12:00 PM
const filledEvent: SchedulerEvent = {
id: 'evt-filled',
title: 'Filled Variant Event',
style: {
variant: 'filled',
color: '#0485f7',
textColor: '#ffffff',
},
};2. Bordered Variant
Solid background fill framed by a customizable border stroke.
| Field | Default / behavior |
|---|---|
backgroundColor | Defaults to color at 14% opacity. |
borderColor | Defaults to color. |
borderWidth | Border width in pixels; defaults to 1.5. |
dashedBorder | Uses a dashed border when true; defaults to false. |
Bordered Variant
09:00 AM to 12:00 PM
const borderedEvent: SchedulerEvent = {
id: 'evt-bordered',
title: 'Bordered Variant Event',
style: {
variant: 'bordered',
color: '#ec4899',
borderColor: '#db2777',
borderWidth: 2,
dashedBorder: false,
backgroundColor: '#fce7f3',
},
};3. Outlined Variant
Clean, transparent background framed by a distinct border.
| Field | Default / behavior |
|---|---|
borderColor | Defaults to color. |
borderWidth | Border width in pixels; defaults to 1.5. |
dashedBorder | Uses a dashed border when true; defaults to false. |
Outlined Variant
09:00 AM to 12:00 PM
const outlinedEvent: SchedulerEvent = {
id: 'evt-outlined',
title: 'Outlined Variant Event',
style: {
variant: 'outlined',
borderColor: '#8b5cf6',
borderWidth: 2,
color: '#7c3aed',
},
};4. Line Variant
Horizontal accent bars support titles above, centered within, or below the line. Set dashedLine to use the scheduler's dashed treatment.
| Field | Default / behavior |
|---|---|
backgroundColor | Defaults to color; controls the solid line fill. |
dashedLine | Uses the repeating dashed-line treatment when true; defaults to false. |
lineTitlePosition | 'hidden', 'left-top', 'center', or 'left-bottom'; defaults to hidden. |
const solidLineEvent: SchedulerEvent = {
id: 'evt-line-solid',
title: 'Title above the line',
style: {
variant: 'line',
color: '#0485f7',
lineTitlePosition: 'left-top',
},
};
const dashedLineEvent: SchedulerEvent = {
id: 'evt-line-dashed',
title: 'Centered dashed line',
style: {
variant: 'line',
color: '#8b5cf6',
dashedLine: true,
lineTitlePosition: 'center',
},
};
// lineTitlePosition: 'hidden' | 'left-top' | 'center' | 'left-bottom'5. Indented Variant
Left accent pill treatment with soft background fill.
| Field | Default / behavior |
|---|---|
accentColor | Color of the left accent; defaults to color. |
backgroundColor | Defaults to color at 10% opacity. |
Indented Variant
09:00 AM to 12:00 PM
const indentedEvent: SchedulerEvent = {
id: 'evt-indented',
title: 'Indented Variant Event',
style: {
variant: 'indented',
accentColor: '#10b981',
backgroundColor: '#d1fae5',
color: '#065f46',
},
};6. Rounded Pill Variant
Capsule shape with fully rounded pill ends. Its content uses additional horizontal inset so the title and time stay clear of the curved edge.
| Field | Default / behavior |
|---|---|
color | Primary capsule fill; defaults to '#3b82f6'. |
backgroundColor | Overrides the fill without changing color. |
textColor | Defaults to white. |
Rounded Variant
09:00 AM to 12:00 PM
const roundedEvent: SchedulerEvent = {
id: 'evt-rounded',
title: 'Rounded Pill Variant',
style: {
variant: 'rounded',
color: '#f59e0b',
textColor: '#ffffff',
},
};Milestone Markers (MilestoneMarkerType)
Milestones represent point-in-time events (where start === end or displayMode: 'milestone'). Rather than spanning a timeline range, milestones render as localized node markers using @dayflow-scheduler/core's native marker components.
DayFlow supports 3 official milestone marker types via the milestoneMarker property:
| Marker Type | Key | Visual Representation |
|---|---|---|
| Diamond | 'diamond' | Solid rotated diamond node. |
| Flag | 'flag' | Native SVG flag milestone icon. |
| Milestone | 'milestone' | Native SVG milestone node marker. |
| Milestone field | Type | Default / behavior |
|---|---|---|
style.milestoneMarker | 'diamond' | 'flag' | 'milestone' | Marker shape; defaults to 'diamond'. |
event.displayMode | 'milestone' | Explicitly renders a milestone. Equal start and end values also infer milestone rendering. |
milestoneLabelDisplay | 'hover' | 'always' | Scheduler-wide label behavior; defaults to 'hover'. |
Labels for milestone markers support two display modes:
'hover'(default): The label remains hidden until the marker is hovered or selected.'always': The label is permanently displayed next to the marker.
Configure the label mode on the scheduler, not on each event:
const app = useSchedulerApp({
resources,
events,
milestoneLabelDisplay: 'always', // 'hover' | 'always'
});1. Diamond Marker ('diamond')
const diamondMilestone: SchedulerEvent = {
id: 'm-diamond',
title: 'Diamond Milestone',
start: '2026-08-15T09:00:00',
end: '2026-08-15T09:00:00',
style: {
variant: 'filled',
color: '#0485f7',
milestoneMarker: 'diamond',
},
};2. Flag Marker ('flag')
const flagMilestone: SchedulerEvent = {
id: 'm-flag',
title: 'Flag Milestone',
start: '2026-08-15T09:00:00',
end: '2026-08-15T09:00:00',
style: {
variant: 'filled',
color: '#f43f5e',
milestoneMarker: 'flag',
},
};3. Milestone Marker ('milestone')
const pinMilestone: SchedulerEvent = {
id: 'm-milestone',
title: 'Milestone Marker',
start: '2026-08-15T09:00:00',
end: '2026-08-15T09:00:00',
style: {
variant: 'filled',
color: '#10b981',
milestoneMarker: 'milestone',
},
};Advanced Style Features
1. Interactive Progress Bars (progress)
Progress supports two display modes:
fill: The unfinished portion is overlaid across the event background.inline-bar: A compact progress track is rendered along the bottom of the event.
Both demos use the scheduler's internal progress-resize handle. Hover an event and drag the handle, or focus it and use the left and right arrow keys. Use the Animate progress checkbox to compare the static and animated treatments.
Set animate: true to add a moving stripe treatment while retaining a numeric progress value. For indeterminate work, value: 'animate' renders a continuously animated scan without a fixed percentage.
| Progress field | Type | Default / behavior |
|---|---|---|
event.progress | number | Runtime value from 0 to 100. It overrides style.progress.value, which is useful when progress changes independently. |
style.progress.value | number | 'animate' | Numeric completion, or 'animate' for an indeterminate scan. |
style.progress.color | ColorValue | Color of the completed fill or inline bar; inferred from the variant by default. |
style.progress.trackColor | ColorValue | Color of the unfinished inline track; inferred by default. |
style.progress.display | 'inline-bar' | 'fill' | Compact bottom bar or background-fill presentation; defaults to 'inline-bar'. |
style.progress.animate | boolean | Adds moving stripes to numeric progress; defaults to false. |
onEventProgressResize(event, value) | callback | Receives progress updates from the event's drag/keyboard handle so the value can be persisted. |
Fill Progress Task
09:00 AM to 12:00 PM
Inline Progress Task
09:00 AM to 12:00 PM
const fillProgressEvent: SchedulerEvent = {
id: 'task-progress-fill',
title: 'Fill Progress Task',
progress: 68,
style: {
variant: 'filled',
color: '#61a6fb',
progress: {
value: 68,
color: '#61a6fb',
display: 'fill', // 'inline-bar' | 'fill'
},
},
};
const animatedInlineProgressEvent: SchedulerEvent = {
id: 'task-progress-inline',
title: 'Inline Progress Task',
progress: 42,
style: {
variant: 'filled',
color: '#7cc784',
progress: {
value: 42,
color: '#b8e3bd',
display: 'inline-bar',
animate: true,
},
},
};
const app = useSchedulerApp({
events: [fillProgressEvent, animatedInlineProgressEvent],
onEventProgressResize: (event, progress) => {
// Persist the updated event/progress to your data source.
},
});2. Gradient Fills (gradient)
Apply smooth direction-controlled color gradients:
| Gradient field | Type | Default / behavior |
|---|---|---|
gradient.color | ColorValue | Required ending color. |
gradient.direction | string | Any CSS linear-gradient direction, such as '135deg'; defaults to '90deg'. |
Gradient Event
09:00 AM to 12:00 PM
const gradientEvent: SchedulerEvent = {
id: 'grad-event',
title: 'Gradient Fill Event',
style: {
variant: 'filled',
gradient: {
color: { light: '#0485f7', dark: '#60a5fa' },
direction: '135deg',
},
textColor: '#ffffff',
},
};3. Pattern Overlays (pattern)
Add stripe or hatch textures for tentative or blocked schedules:
| Pattern field | Type | Default / behavior |
|---|---|---|
pattern.color | ColorValue | Stripe color. An rgba() alpha is preserved unless opacity is set. |
pattern.backgroundColor | ColorValue | Optional base color behind the stripe layer; inferred by default. |
pattern.opacity | number | Explicit stripe opacity from 0 to 1; defaults to the color alpha or 0.12. |
pattern.size | number | Stripe repeat size in pixels; defaults to 8 and is clamped to a minimum of 6. |
Pattern Hatch
09:00 AM to 12:00 PM
const patternEvent: SchedulerEvent = {
id: 'pattern-event',
title: 'Tentative Pattern Hatch',
style: {
variant: 'outlined',
borderColor: '#64748b',
color: '#334155',
pattern: {
color: 'rgba(100, 116, 139, 0.2)',
size: 8,
},
},
};4. Multi-color Splits (split)
Divide the event into multiple color bands for multi-category events:
| Split field | Type | Default / behavior |
|---|---|---|
split.colors | ColorValue[] | Required list of two or more equal color sections. |
split.direction | 'horizontal' | 'vertical' | Section arrangement; defaults to 'horizontal'. |
Split Dual Colors
09:00 AM to 12:00 PM
const splitEvent: SchedulerEvent = {
id: 'split-event',
title: 'Multi-color Split Badge',
style: {
variant: 'filled',
split: {
colors: ['#0485f7', '#ec4899'],
direction: 'horizontal',
},
textColor: '#ffffff',
},
};5. Icon Glyph Decoration (icon)
Add glyph icons to event headers:
| Icon field | Type | Default / behavior |
|---|---|---|
icon.glyph | string | Unicode character or emoji used as the leading icon. |
icon.src | string | Image URL used instead of glyph. |
icon.alt | string | Alternative text for an icon image; defaults to ''. |
icon.color | ColorValue | Glyph color; defaults to textColor. |
Icon Call Event
09:00 AM to 12:00 PM
const iconEvent: SchedulerEvent = {
id: 'icon-event',
title: 'Icon Call Event',
style: {
variant: 'filled',
color: '#0485f7',
textColor: '#ffffff',
icon: {
glyph: '☎',
},
},
};Central Style Registry (styleRegistry)
For scalable design systems, define reusable style specifications in a styleRegistry and reference them by styleId:
| Registry field | Type | Purpose |
|---|---|---|
event.styleId | string | Direct key into styleRegistry. |
styleRegistry | Record<string, EventStyleSpec> | Scheduler-level dictionary of reusable named styles. |
getEventStyleId | (event) => string | undefined | Dynamically derives a registry key and takes priority over event.styleId. |
allowedStylePresetIds | EventStylePresetId[] | Limits which presets appear in the built-in event detail editor. |
import {
useSchedulerApp,
createDayView,
type EventStyleSpec,
} from '@dayflow-scheduler/react';
const styleRegistry: Record<string, EventStyleSpec> = {
'filled-blue': {
variant: 'filled',
color: '#0485f7',
textColor: '#ffffff',
},
'flag-rose': {
variant: 'filled',
color: '#f43f5e',
milestoneMarker: 'flag',
},
};
export function MyScheduler() {
const app = useSchedulerApp({
resources,
events: [
{
id: 'e1',
title: 'Task A',
start: '...',
end: '...',
styleId: 'filled-blue',
},
{
id: 'e2',
title: 'Milestone',
start: '...',
end: '...',
styleId: 'flag-rose',
},
],
views: [createDayView()],
styleRegistry,
});
return <DayflowScheduler app={app} />;
}event.styleId is resolved directly. Use getEventStyleId only when the style key needs to be derived dynamically from other event data.
Style resolution follows this priority: getEventStyleId(event) / event.styleId → event.style → event.color + event.variant → resource style → scheduler fallback.