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:

VariantKeyDescription
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 entryWhen to use
event.styleApply a complete inline EventStyleSpec, including decorations.
event.colorChange only the event's primary color without creating a style object.
event.variantSelect a structure alongside event.color or the resource's base color.
Common fieldTypeDefault / behavior
style.variantEventVariantRequired in event.style; selects one of the six structures above.
style.colorColorValuePrimary fill, stroke, or accent color. Accepts a CSS color or { light, dark } theme-aware pair.
style.textColorColorValueInferred from the variant unless explicitly set.
style.opacitynumberOpacity of the complete event visual from 0 to 1; defaults to 1.
style.borderRadiusnumberCorner 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.

FieldDefault / behavior
colorPrimary fill color; defaults to '#3b82f6'.
backgroundColorOverrides the fill without changing color.
textColorDefaults 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.

FieldDefault / behavior
backgroundColorDefaults to color at 14% opacity.
borderColorDefaults to color.
borderWidthBorder width in pixels; defaults to 1.5.
dashedBorderUses 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.

FieldDefault / behavior
borderColorDefaults to color.
borderWidthBorder width in pixels; defaults to 1.5.
dashedBorderUses 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.

FieldDefault / behavior
backgroundColorDefaults to color; controls the solid line fill.
dashedLineUses the repeating dashed-line treatment when true; defaults to false.
lineTitlePosition'hidden', 'left-top', 'center', or 'left-bottom'; defaults to hidden.
Solid · left-top
Title above the line
Dashed · center
Centered dashed line
Solid · left-bottom
Title below the line
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.

FieldDefault / behavior
accentColorColor of the left accent; defaults to color.
backgroundColorDefaults 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.

FieldDefault / behavior
colorPrimary capsule fill; defaults to '#3b82f6'.
backgroundColorOverrides the fill without changing color.
textColorDefaults 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 TypeKeyVisual Representation
Diamond'diamond'Solid rotated diamond node.
Flag'flag'Native SVG flag milestone icon.
Milestone'milestone'Native SVG milestone node marker.
Milestone fieldTypeDefault / 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')

Always Visible Label Mode:
Diamond MilestoneAug 15 · 09:00 AM
Hover Label Mode (Hover marker to inspect):
Diamond Milestone (Hover)Aug 15 · 09:00 AM
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')

Always Visible Label Mode:
Flag MilestoneAug 15 · 09:00 AM
Hover Label Mode (Hover marker to inspect):
Flag Milestone (Hover)Aug 15 · 09:00 AM
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')

Always Visible Label Mode:
Milestone MarkerAug 15 · 09:00 AM
Hover Label Mode (Hover marker to inspect):
Milestone Marker (Hover)Aug 15 · 09:00 AM
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 fieldTypeDefault / behavior
event.progressnumberRuntime value from 0 to 100. It overrides style.progress.value, which is useful when progress changes independently.
style.progress.valuenumber | 'animate'Numeric completion, or 'animate' for an indeterminate scan.
style.progress.colorColorValueColor of the completed fill or inline bar; inferred from the variant by default.
style.progress.trackColorColorValueColor 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.animatebooleanAdds moving stripes to numeric progress; defaults to false.
onEventProgressResize(event, value)callbackReceives progress updates from the event's drag/keyboard handle so the value can be persisted.
fill
Completion: 68%

Fill Progress Task

09:00 AM to 12:00 PM

inline-bar
Completion: 42%

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 fieldTypeDefault / behavior
gradient.colorColorValueRequired ending color.
gradient.directionstringAny 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 fieldTypeDefault / behavior
pattern.colorColorValueStripe color. An rgba() alpha is preserved unless opacity is set.
pattern.backgroundColorColorValueOptional base color behind the stripe layer; inferred by default.
pattern.opacitynumberExplicit stripe opacity from 0 to 1; defaults to the color alpha or 0.12.
pattern.sizenumberStripe 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 fieldTypeDefault / behavior
split.colorsColorValue[]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 fieldTypeDefault / behavior
icon.glyphstringUnicode character or emoji used as the leading icon.
icon.srcstringImage URL used instead of glyph.
icon.altstringAlternative text for an icon image; defaults to ''.
icon.colorColorValueGlyph 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 fieldTypePurpose
event.styleIdstringDirect key into styleRegistry.
styleRegistryRecord<string, EventStyleSpec>Scheduler-level dictionary of reusable named styles.
getEventStyleId(event) => string | undefinedDynamically derives a registry key and takes priority over event.styleId.
allowedStylePresetIdsEventStylePresetId[]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.

On this page