Skip to content

Commit a821f4e

Browse files
committed
[dev] add description for custom recurring modal
1 parent 29d595d commit a821f4e

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

docs/guides/recurring-events.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,48 @@ For example:
471471
addEventListener(node, "click", function(){...})
472472
~~~
473473

474+
## Custom confirmation modal
475+
476+
When a user edits or drags a recurring event, the scheduler displays a built-in modal that asks whether to modify just this occurrence, this and following events, or the entire series. You can replace it with your own UI by overriding `scheduler.ext.recurring.confirm`.
477+
478+
~~~js
479+
scheduler.ext.recurring.confirm = function(context) {
480+
// context contains:
481+
// - origin: "lightbox" | "dnd"
482+
// - occurrence: the occurrence event object
483+
// - series: the parent series event object
484+
// - labels: { title, ok, cancel, occurrence, following, series }
485+
// - options: ["occurrence", "following", "series"]
486+
//
487+
// Return one of: "occurrence", "following", "series", or null to cancel.
488+
// Can return a Promise for async UI.
489+
490+
return new Promise(function(resolve) {
491+
myCustomDialog.show({
492+
title: context.labels.title,
493+
options: context.options,
494+
onSelect: function(choice) { resolve(choice); },
495+
onCancel: function() { resolve(null); }
496+
});
497+
});
498+
};
499+
~~~
500+
501+
The context object has the following properties:
502+
503+
| Property | Type | Description |
504+
|---|---|---|
505+
| `origin` | `"lightbox" \| "dnd"` | Whether the action was triggered from the lightbox or drag-and-drop |
506+
| `occurrence` | `object` | The specific occurrence being edited |
507+
| `series` | `object` | The parent recurring event |
508+
| `labels` | `object` | Localized strings: `title`, `ok`, `cancel`, `occurrence`, `following`, `series` |
509+
| `options` | `string[]` | Available choices, e.g. `["occurrence", "following", "series"]` |
510+
511+
The function must return `"occurrence"`, `"following"`, `"series"`, or `null` to cancel. It can return the value directly or as a Promise.
512+
513+
For a React implementation, see the [React Scheduler documentation](integrations/react/overview.md#customizing-the-recurrence-confirmation-modal).
514+
515+
474516
## Legacy format of recurring events
475517

476518
Until v7.1 Scheduler used a custom format for recurring events, you can find the format details [here](guides/recurring-events-legacy.md).

docs/integrations/react/overview.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,75 @@ The delete confirmation dialog can be overridden via `modals`.
351351
/>
352352
```
353353
354+
### Customizing the Recurrence Confirmation Modal
355+
356+
When a user edits or drags a recurring event, a confirmation modal asks whether to modify just this occurrence, this and following events, or the entire series. You can replace this built-in dialog with your own using `modals.onRecurrenceConfirm`.
357+
358+
The callback receives a context object and must return a decision (or a Promise that resolves to one):
359+
360+
| Field | Type | Description |
361+
|---|---|---|
362+
| `origin` | `"lightbox" \| "dnd"` | Whether the action was triggered from the lightbox or drag-and-drop |
363+
| `occurrence` | `any` | The specific occurrence being edited |
364+
| `series` | `any` | The parent recurring event |
365+
| `labels` | `object` | Localized labels: `title`, `ok`, `cancel`, `occurrence`, `following`, `series` |
366+
| `options` | `string[]` | Available choices, e.g. `["occurrence", "following", "series"]` |
367+
368+
Return value (`RecurrenceDecision`): `"occurrence"`, `"following"`, `"series"`, or `null` to cancel.
369+
370+
Minimal example using `window.confirm`:
371+
372+
```tsx
373+
<ReactScheduler
374+
modals={{
375+
onRecurrenceConfirm: (context) => {
376+
const choice = window.prompt(
377+
`${context.labels.title}\nOptions: ${context.options.join(", ")}`
378+
);
379+
return context.options.includes(choice) ? choice : null;
380+
},
381+
}}
382+
/>
383+
```
384+
385+
Full example with a custom React dialog:
386+
387+
```tsx
388+
import { useState, useCallback } from "react";
389+
390+
function App() {
391+
const [recurrencePrompt, setRecurrencePrompt] = useState(null);
392+
393+
const onRecurrenceConfirm = useCallback((context) => {
394+
return new Promise((resolve) => {
395+
setRecurrencePrompt({ context, resolve });
396+
});
397+
}, []);
398+
399+
return (
400+
<>
401+
<ReactScheduler
402+
modals={{ onRecurrenceConfirm }}
403+
/>
404+
{recurrencePrompt && (
405+
<MyRecurrenceDialog
406+
options={recurrencePrompt.context.options}
407+
labels={recurrencePrompt.context.labels}
408+
onSelect={(choice) => {
409+
recurrencePrompt.resolve(choice);
410+
setRecurrencePrompt(null);
411+
}}
412+
onCancel={() => {
413+
recurrencePrompt.resolve(null);
414+
setRecurrencePrompt(null);
415+
}}
416+
/>
417+
)}
418+
</>
419+
);
420+
}
421+
```
422+
354423
## Filtering
355424
356425
Use the `filter` prop to control which events are displayed:

0 commit comments

Comments
 (0)