Skip to main content

Editor

A React component that wraps the Editor from @svar-ui/react-editor and binds it to the currently selected calendar event. It mounts when api.getReactiveState().editorData carries a selection and forwards form changes back to the calendar through update-event, delete-event, and select-event. Placement is responsive and the field list is recurrence-aware. The form model, item and validation contract, save lifecycle, and placement behavior come from the upstream Editor.

Signature

import { Editor } from "@svar-ui/react-calendar";

type EditorProps = {
api: CalendarInstanceApi;
items?: EditorItem[];
placement?: "inline" | "sidebar" | "modal" | "fullscreen";
layout?: "columns" | "default";
focus?: boolean;
css?: string;
topBar?: any;
autoSave?: boolean;
onChange?: (ev: {
key: string;
value: any;
update: Record<string, any>;
}) => void;
onSave?: (ev: { values: Record<string, any> }) => void;
onAction?: (ev: {
item: { id: string; comp?: string };
changes?: any;
}) => void;
};

Only api is calendar-specific. Any prop the wrapper does not handle is forwarded to the underlying Editor. The values prop is not accepted - the wrapper always binds the form to editorData.values.

Props

PropTypeDefaultDescription
apiCalendarInstanceApirequiredCalendar instance from ref or init. Used to read editorData and dispatch actions.
itemsEditorItem[]getEditorItems(useRecurringForm)Field config passed to @svar-ui/react-editor. Defaults to the recurrence-aware calendar field list.
placement"inline" | "sidebar" | "modal" | "fullscreen"responsiveWhere the editor is rendered. When omitted, resolved at runtime: "fullscreen" for a compact calendar (root width below 480px), otherwise "sidebar". An explicit value forwards unchanged.
layout"columns" | "default""default"Layout preset for the underlying editor.
focusbooleantrueForwarded to @svar-ui/react-editor.
cssstring""Extra class appended to the editor's CSS class list.
topBaranydefault top barOverride the injected top bar; pass null to remove it.
autoSavebooleantruePushes field changes through update-event immediately.
onChange(ev) => voidundefinedFires after the wrapper's same-day end-date adjustment runs.
onSave(ev) => voidundefinedFires before update-event is dispatched (manual-save flow).
onAction(ev) => voidundefinedFires before built-in close handling on top/bottom-bar buttons.

The wrapper adds the wx-editor-calendar class to every instance; caller css is appended after it. In sidebar placement the calendar stylesheet sets the editor width to 450px.

Calendar-owned pieces

Beyond mounting and placement, the wrapper owns the calendar integration; the rest is upstream:

  • Selection state comes from editorData - id and rawId are the action targets, values is the editable data, and recurring/recurringMode/recurringOriginalDate drive recurring edits. Form edits can't overwrite these because they live outside values.
  • The default field list registers two calendar items: event-dates (start/end/allDay) in every build, and event-recurrence (adds rrule) in Pro. getEditorItems(true) swaps in the recurrence form.
  • Save, delete, and close map to calendar actions: onSave dispatches update-event, the Delete button dispatches delete-event({ id, rawId }) then clears selection, and a close action clears selection via select-event({ id: null, rawId: null }).

Built-in top bar

When topBar is left undefined, the wrapper renders a close icon and a Delete button:

ControlAction
Close iconselect-event({ id: null })
Delete buttondelete-event({ id }), then select-event({ id: null })

Pass topBar={null} to remove it, or pass a custom { items: [...] } to replace it.

Example

import { useRef, useState } from "react";
import { Calendar, Editor } from "@svar-ui/react-calendar";

function App() {
const [api, setApi] = useState(null);

return (
<>
<Calendar init={setApi} events={events} date={date} />
{api && <Editor api={api} />}
</>
);
}