Skip to content
kerfjsGitHub

MoveSheet

A sheet to move an event by picking a day, a time and a length, without dragging.

SourcePackage @kerf-js/veneer

Preview

tsx
import { state } from '@kerf-js/core'import {  Button,  Card,  MoveSheet,  Row,  Stack,  Text} from '@kerf-js/veneer'import { at } from '@kerf-js/veneer-core'import type { CalEvent, Slot } from '@kerf-js/veneer-core'export function Reschedule() {  const open = state(false)  const event = state(REVIEW)  const move = (e: CalEvent, to: Slot) =>    (event.value = {      ...e,      start: at(to.date, to.s),      end: at(to.date, to.e),    })  return (    <Card      title={event.value.title}      sweep={false}    >      <Stack gap="related">        <Text subtle>{when(event.value)}</Text>        <Row>          <Button            emphasis="outline"            tone="neutral"            onClick={() => (open.value = true)}          >            Move          </Button>        </Row>      </Stack>      <MoveSheet        open={open}        event={event.value}        events={TEAM_EVENTS}        firstDayOfWeek={1}        locale="en-GB"        hourCycle="h23"        onMove={move}      />    </Card>  )}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')!const when = (e: CalEvent) => {  const date = e.start.slice(0, 10)  const start = e.start.slice(11)  const end = e.end.slice(11)  return `${date}, ${start} to ${end}`}

Installation

npm install @kerf-js/veneer

Usage

tsx
import { MoveSheet } from '@kerf-js/veneer'

When to use

Use it for

  • Moving an event on a touch screen
  • Any time a drag is not an option

Accessibility

  • This has no shortcuts of its own: controls inside it use Tab, Enter and Space as usual, and veneer's parts keep their roles and labels.

API Reference

PropTypeDefaultDescription
openState<boolean>—A state you own.
eventCalEvent | null—The event to move.
eventsCalEvent[]—The rest of the calendar.
firstDayOfWeeknumber—The day the week strip starts on, 0 for Sunday to 6. Default 1, Monday.
localestring—The language and region used to format values.
hourCyclestring—h12 for AM and PM, h23 for a 24-hour clock. The locale's otherwise.
stepnumber—Minutes per press of Shorter or Longer.
EventTypeDefaultDescription
onMove(e: CalEvent, to: Slot) => void—Gets the event and where it should go.
onClose(() => void)—It closed.

RelatedAgendaEvent editor