Draft
Automatic draft saving to prevent data loss from accidental page closures.
When To Use
- Long forms with risk of data loss
- Complex configuration editing
- Offline editing with local storage
Examples
API#
DraftMonitor
| Property | Description | Type | Default |
|---|---|---|---|
| Data | Data to monitor | TData | - |
| DataChanged | Change callback | EventCallback<TData> | - |
| Options | Draft options | DraftOptions | - |
| Enabled | Enable draft | bool | true |
| Locale | Localization | DraftLocale | - |
| RecoveryContentTemplate | Custom dialog template | RenderFragment<DraftData<TData>> | - |
| OnRecovered | Recovery callback | EventCallback<TData> | - |
| OnDeleted | Deletion callback | EventCallback | - |
Methods:
SaveDraftAsync()- Manually save draftClearDraftAsync()- Clear draft
DraftOptions
| Property | Description | Type | Default |
|---|---|---|---|
| Key | Draft identifier | string | - |
| DelayMilliseconds | Save delay (ms) | int | 1000 |
| RecoveryMode | Recovery mode | DraftRecoveryMode | Confirm |
| Version | Version number | string | "1.0.0" |
| EnableVersionCheck | Version check | bool | true |
| Enabled | Enable draft | bool | true |
| StorageProvider | Storage provider | IDraftStorageProvider | null |
| ShouldRecoverDraft | Custom version comparison function. (draftVersion, currentVersion) => bool | Func<string, string, bool> | null |
DraftRecoveryMode
| Value | Description |
|---|---|
| Confirm | Show confirmation dialog |
| Auto | Auto-recover |
| Manual | Manual handling |
DraftLocale
| Property | Description | Default |
|---|---|---|
| RecoveryTitle | Dialog title | "Draft Found" |
| RecoveryContent | Dialog content template (supports {time} placeholder) |
"An unfinished draft was detected. Would you like to recover it?\n\nSaved at: {time}" |
| RecoveryOkText | Confirm button | "Recover" |
| RecoveryCancelText | Cancel button | "Delete" |
Advanced
Custom Storage
public class DbDraftProvider : IDraftStorageProvider
{
public async Task SaveAsync(string key, string data) { /* DB save */ }
public async Task<string> LoadAsync(string key) { /* DB load */ }
public async Task RemoveAsync(string key) { /* DB remove */ }
public async Task<bool> ExistsAsync(string key) { /* DB check */ }
}
builder.Services.AddAntDesign();
builder.Services.AddScoped<IDraftStorageProvider, DbDraftProvider>();
Using IDraftService Directly
@inject IDraftService DraftService
@code {
private async Task SaveDraft()
{
await DraftService.SaveDraftAsync("my-key", myData, options);
}
private async Task<MyData> LoadDraft()
{
var draft = await DraftService.LoadDraftAsync<MyData>("my-key", options);
return draft?.Data;
}
private async Task RemoveDraft()
{
await DraftService.RemoveDraftAsync("my-key");
}
}
Notes
- Version Control: Update version when data structure changes
- Storage Limits: LocalStorage ~5-10MB, use custom provider for larger data
- Security: Don't store sensitive data or use encryption
- Cleanup: Regularly clean expired drafts
- Multi-Tab: LocalStorage shared across tabs, use unique keys if needed