EventPopover
A small card with an event's details, hung from wherever it was opened.
SourcePackage @kerf-js/veneer
Preview
tsx
import { state } from '@kerf-js/core'import { Button, EventPopover, Stack, Text} from '@kerf-js/veneer'import type { CalEvent } from '@kerf-js/veneer-core'export function Details() { const open = state(false) const said = state( 'Open the event, then join, edit or delete it.', ) let opener: HTMLElement | undefined return ( <Stack gap="related" align="center" > <Button ref={(n: HTMLElement) => (opener = n)} emphasis="outline" tone="neutral" onClick={() => (open.value = !open.value)} > {REVIEW.title} </Button> <Text role="caption" subtle > {said.value} </Text> <EventPopover event={REVIEW} open={open} anchor={() => opener} side="bottom" align="center" zoneLabel="Stockholm (CET)" locale="en-GB" hourCycle="h23" onJoin={() => (said.value = 'Joining the call')} onEdit={() => (said.value = 'Editing')} onDelete={() => (said.value = 'Deleted')} /> </Stack> )}const TEAM_EVENTS: CalEvent[] = [ { id: 'e1', title: 'Platform standup', start: '2026-11-02T09:00', end: '2026-11-02T09:15', cal: 1, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR', location: 'Room Atlas', attendees: ['Mara Lindqvist', 'Jun Tanaka'], }, { id: 'e2', title: 'Platform standup', start: '2026-11-03T09:00', end: '2026-11-03T09:15', cal: 1, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR', location: 'Room Atlas', attendees: ['Mara Lindqvist', 'Jun Tanaka'], }, { id: 'e3', title: 'Checkout review', start: '2026-11-03T10:00', end: '2026-11-03T11:00', cal: 2, video: true, attendees: [ 'Priya Raman', 'Tomás Oliveira', 'Mara Lindqvist', ], }, { id: 'e4', title: 'Incident review: mobile-bff', start: '2026-11-03T13:00', end: '2026-11-03T13:45', cal: 4, video: true, location: 'Room Birch', attendees: ['Sam Okafor', 'Inés Vidal', 'Jun Tanaka'], }, { id: 'e5', title: 'Ranking v2 handover', start: '2026-11-03T15:00', end: '2026-11-03T16:00', cal: 3, location: 'Room Cedar', attendees: ['Lena Fischer', 'Noor Haddad'], }, { id: 'e6', title: 'Priya out of office', start: '2026-11-03', end: '2026-11-03', allDay: true, cal: 6, }, { id: 'e7', title: 'Release 2026.11', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 5, attendees: [ 'Mara Lindqvist', 'Jun Tanaka', 'Tomás Oliveira', ], }, { id: 'e8', title: 'Design crit', start: '2026-11-04T14:00', end: '2026-11-04T15:00', cal: 2, tentative: true, video: true, }, { id: 'e9', title: 'Cost review', start: '2026-11-05T10:00', end: '2026-11-05T11:00', cal: 1, recurrence: 'FREQ=MONTHLY', attendees: ['Mara Lindqvist', 'Lena Fischer'], }, { id: 'e10', title: 'On-call handover', start: '2026-11-06T16:00', end: '2026-11-06T16:30', cal: 1, recurrence: 'FREQ=WEEKLY', video: true, },]const REVIEW = TEAM_EVENTS.find((e) => e.id === 'e4')!Installation
npm install @kerf-js/veneerUsage
tsx
import { EventPopover } from '@kerf-js/veneer'Accessibility
- Escape
- Closes and returns to the event
- It is a non-modal dialog, so the rest of the page stays usable.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
event | CalEvent | null | — | The event to show. |
open | State<boolean> | — | A state you own. |
anchor | () => HTMLElement | — | Returns the element it hangs from. Focus goes back there. |
zoneLabel | string | — | Such as "Stockholm (CET)". |
locale | string | — | The language and region used to format values. |
hourCycle | string | — | h12 for AM and PM, h23 for a 24-hour clock. The locale's otherwise. |
side | Side | — | Which edge it sits on. |
align | Align | — | How it lines up with what opened it. |
| Event | Type | Default | Description |
|---|---|---|---|
onEdit | ((e: CalEvent) => void) | — | Adds Edit. |
onDelete | ((e: CalEvent) => void) | — | Adds Delete. |
onJoin | ((e: CalEvent) => void) | — | Join was pressed. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="popover"] [data-part="content"]
contenttitleactions
RelatedEvent editorPopover