Source: https://monarchui.dev/components/event-chip/

Components · Date, time and scheduling

# EventChip

One event in a calendar view: colour, title, time and status, as a button or link.

@rookcom/monarch-react/scheduling

Component

## Dot chips (month cell)

## Usage examples

### Bar chips (agenda, all-day row)

### Block chips (time grid)

### As a link or popover trigger

## Purpose

Shows one event the same way in every calendar view (month cell, agenda row, time grid block) and opens it. Needed by: calendar.

### Use when

- An event must appear inside CalendarMonthView, AgendaList or TimeGrid; those views render it for you.
- A custom view (a list of upcoming bookings, a day summary in a card) needs events that look and read like the calendar’s.

### Avoid when

- The item is not a time-bound event: use Badge or StatusBadge for labels and states.
- You need a full event card with actions: put those in the popover or page the chip opens.

## Design principles

- The product colour is only a marker, a bar and a light tint; text stays on Monarch text tokens, so any calendar colour stays readable in every theme.
- Status is never colour alone: tentative is hollow or dashed, cancelled and declined are muted and struck through, and the status word is part of the accessible name (and visible text in `bar` and `block`).
- The accessible name always reads "title, time, status", even when the visible time is abbreviated (`timeLabel`).
- One element, one action: a button by default, a link with `href`, or your router link with `asChild`.

## API reference

```tsx
import { EventChip } from '@rookcom/monarch-react/scheduling';
```

| Export | Kind | Rendering | Root class |
| --- | --- | --- | --- |
| `EventChip` | component | server-safe | `.mn-event-color` |

Renders a `<button type="button">` (ref to it), an `<a>` when `href` is set, or the child element with `asChild`.

With plain-text `title`, `time`, `timeLabel` and `detail`, the chip gets a computed `aria-label`; with rich content the name comes from the content instead. Pass `aria-label` to override.

`CalendarEvent` is the data shape the calendar views take: `{ id, title, start, end?, allDay?, color?, status?, detail?, href? }`.

Generated from the TypeScript declarations of `packages/react/src/components/scheduling/event-chip`.

## Properties

### `EventChip`

One event in any calendar view: a colour dot or accent bar, the title, the time and its status. It is a button (or a link with `href`) whose accessible name reads "title, time, status", so it can open the product's event detail or popover.

| Prop | Type | Description |
| --- | --- | --- |
| `title` required | `ReactNode` | The event title. Always part of the accessible name. |
| `asChild` | `boolean` | Render the child element (a router link, or a trigger you supply) with the chip's styling and content. The child must be a single element. |
| `children` | `ReactNode` |  |
| `className` | `string` |  |
| `color` | `string` | The event's colour (any CSS colour). It is only ever the marker, bar and a light tint behind the text; text keeps Monarch's text colours, so it stays readable in every theme. Defaults to the product accent. |
| `density` | `"compact" \| "regular"` | `compact` puts a `block` chip on one line (time, then title) for short events. Default `regular`. Exposed as `data-density`. |
| `detail` | `ReactNode` | A second, muted line in `bar` and `block` chips. |
| `disabled` | `boolean` |  |
| `id` | `string` |  |
| `past` | `boolean` | The event has ended: drawn faded. Exposed as `data-past`. |
| `status` | `EventChipStatus` | Default `confirmed`. Exposed as `data-status`. |
| `statusLabel` | `string` | Text for the status in the accessible name and in `bar`/`block` chips. Defaults to the English status name. |
| `time` | `ReactNode` | Visible time, short or long: `"09:30"` in a month cell, `"09:30 – 10:15"` in an agenda. Omit for all-day events shown in an all-day row. |
| `timeLabel` | `string` | The full time for assistive technology when `time` is abbreviated, for example `"9:30 to 10:15"` or `"All day"`. When set, the visible `time` is hidden from the accessible name and this text is used instead. |
| `variant` | `EventChipVariant` | Default `dot`. Exposed as `data-variant`. |

## Variants

| Prop | Values | Description |
| --- | --- | --- |
| `variant` | `'dot'``'bar'``'block'` | `dot` (default): one line, colour dot, start time, title (month cells, popovers). `bar`: tinted row with an accent bar, wraps a detail line (agenda, all-day row). `block`: fills its container, stacked lines (time grid). |
| `status` | `'confirmed'``'tentative'``'cancelled'``'declined'` | Exposed as `data-status`; see States. |
| `density (block)` | `'regular'``'compact'` | `compact` puts a short block on one line: start time, then title. |
| `past` | `'true'``'false'` | The event has ended: muted text and a faded marker (`data-past`). |

## States

| State | Exposed as | Behaviour |
| --- | --- | --- |
| Confirmed | `data-status="confirmed"` | Solid marker or bar and tint. |
| Tentative | `data-status="tentative"` | Hollow dot; `bar`/`block` get a lighter tint, an outline and a dashed bar. "Tentative" is in the name. |
| Cancelled / declined | `data-status="cancelled" \| "declined"` | Muted text, struck-through title, grey marker and surface. The status word is in the name. |
| Hover | – | Muted background (`dot`) or a stronger tint (`bar`, `block`). |
| Focus | – | Monarch focus ring on `:focus-visible`; the chip is raised above its neighbours. |

## Interaction behaviour

- Click, Enter or Space activates the chip (`onClick`), or follows the link with `href` / `asChild`.
- It forwards its ref and props, so it can be a PopoverTrigger or DropdownMenuTrigger child directly.

## Keyboard support

| Keys | Action |
| --- | --- |
| Tab | Moves focus to the chip (the calendar views manage which chips are in the tab order). |
| Enter / Space | Activates a button chip; Enter follows a link chip. |

## Accessibility

Role

button (or link)

Accessible name

"Title, time, status, detail", built from the props;

timeLabel

replaces an abbreviated visible time.

- The marker is decorative (`aria-hidden`).
- Status text is always in the name, so screen-reader users get the same information as the visual style.
- Verified with axe in jsdom and in Chromium, Firefox and WebKit on /components/event-chip.
- In forced-colours mode the bar and block get a system-colour border (dashed when tentative).

## Responsive behaviour

- Fills the width it is given and truncates the title with an ellipsis; it never forces its container wider.
- `bar` wraps the detail onto its own line on narrow widths.

## Theme support

- Text, surfaces and borders are Monarch tokens, so light, dark and more-contrast themes apply automatically.
- `color` is mixed into `--mn-color-bg-surface` (14%, 6% when tentative), so the tint follows the theme’s surface.
- Without `color` the chip uses the product accent (`--mn-color-accent-solid`).
- Transitions are removed under `prefers-reduced-motion: reduce`.

## Do and don't

### Do

- Pass `timeLabel` when the visible time is shorter than the event (a start time in a month cell).
- Use the calendar or service colour your product already shows elsewhere.
- Translate `statusLabel` along with the rest of the UI.

### Don't

- Do not put several actions inside a chip; it is one control.
- Do not signal status with colour only, for example a red chip for cancelled: set `status`.
- Do not make a chip with no time unless it is an all-day event, and then say so in `timeLabel`.

## Related components

- [CalendarMonthView](https://monarchui.dev/components/calendar-month-view/): Renders `dot` chips in each day and its "+N more" popover.
- [AgendaList](https://monarchui.dev/components/agenda-list/): Renders `bar` chips grouped by day.
- [TimeGrid](https://monarchui.dev/components/time-grid/): Renders `block` chips laid out by time and `bar` chips in the all-day row.
- [StatusBadge](https://monarchui.dev/components/status-badge/): For states of records that are not events.

## Dependencies

| Kind | Depends on |
| --- | --- |
| npm packages | `@radix-ui/react-slot``react` |
| Monarch components | None |

## Testing coverage

- Button named "title, time, status"; `data-variant`, `data-status` and the colour variable are set.
- Confirmed status is left out of the name; `timeLabel` replaces an abbreviated time.
- `bar` and `block` include status and detail in the name; compact density and `past` are exposed.
- Click, Enter and Space activate it; the ref is forwarded.
- `href` renders a link and `asChild` renders a router link with the chip’s class and content.
- No axe violations in jsdom; renders on the server.

| Check | Covered |
| --- | --- |
| Axe in jsdom | Yes |
| Server rendering | Yes |
| Browser suites | Visual baselines: /__gallery/event-chip; Cross-browser axe: /components/event-chip |

Tests: `packages/react/src/components/scheduling/event-chip`

## All example code

### Dot chips (month cell)

```tsx
import { EventChip } from '@rookcom/monarch-react/scheduling';

<div style={{ display: 'grid', gap: 2, width: 220 }}>
  <EventChip title="Stand-up" time="09:00" color="#0f766e" />
  <EventChip title="Design review" time="11:00" status="tentative" color="#7c3aed" />
  <EventChip title="Retrospective" time="16:00" status="cancelled" color="#c2410c" />
  <EventChip title="Vendor call" time="17:30" status="declined" />
</div>
```

### Bar chips (agenda, all-day row)

```tsx
import { EventChip } from '@rookcom/monarch-react/scheduling';

<div style={{ display: 'grid', gap: 4, maxWidth: 360 }}>
  <EventChip
    variant="bar"
    title="Quarterly planning"
    time="10:00 – 11:30"
    detail="Room 4 · 8 guests"
    color="#2563eb"
  />
  <EventChip variant="bar" title="Team offsite" timeLabel="All day" color="#16a34a" />
  <EventChip
    variant="bar"
    title="Onboarding session"
    time="14:00 – 15:00"
    status="tentative"
    color="#db2777"
  />
</div>
```

### Block chips (time grid)

```tsx
import { EventChip } from '@rookcom/monarch-react/scheduling';

<div style={{ display: 'flex', gap: 8 }}>
  <div style={{ width: 160, height: 72 }}>
    <EventChip
      variant="block"
      title="Interview"
      time="13:00 – 14:00"
      detail="Video call"
      color="#0891b2"
    />
  </div>
  <div style={{ width: 160, height: 24 }}>
    <EventChip
      variant="block"
      density="compact"
      title="Check-in"
      time="15:00"
      timeLabel="15:00 – 15:15"
      color="#0891b2"
    />
  </div>
  <div style={{ width: 160, height: 72 }}>
    <EventChip variant="block" title="1:1" time="09:00 – 09:30" past />
  </div>
</div>
```

### As a link or popover trigger

```tsx
import { EventChip } from '@rookcom/monarch-react/scheduling';

<div style={{ width: 220 }}>
  <EventChip href="#/components/event-chip" title="Launch review" time="10:00" />
</div>
```
