算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
forgiveness-undo-and-soft-delete【设计与创意】Use this skill when designing reversibility — undo systems, soft delete, archive-with-recovery, version history, "Undo Send" patterns, and any mechanism that lets a user step back from an action they regret. Trigger when designing destructive actions you want to be safe rather than friction-heavy, when picking between confirmation dialogs and undo to…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
forgiveness; read that first.'Reversibility is the highest-leverage form of forgiveness short of structural prevention. It makes destructive actions safe by allowing recovery — users keep speed (no friction up front) and safety (the action is undoable). Whenever an action can be made reversible, that's almost always preferable to confirming it.
Different actions need different reversibility approaches:
The classic. The user takes an action; pressing Cmd-Z (or Ctrl-Z) reverses it. Multi-level undo lets the user back out through a sequence of actions.
When it applies: editing operations on a single object — text editing, image manipulation, design tool actions, code edits.
Implementation pattern:
const undoStack = [];
const redoStack = [];
function executeAction(action) {
action.do();
undoStack.push(action);
redoStack.length = 0;
}
function undo() {
const action = undoStack.pop();
if (!action) return;
action.undo();
redoStack.push(action);
}
function redo() {
const action = redoStack.pop();
if (!action) return;
action.do();
undoStack.push(action);
}
The user takes an action that destroys or moves data; a toast appears with an "Undo" button for several seconds.
When it applies: archive, delete, move-to-folder, mark-read, and similar one-shot list actions.
Implementation pattern:
async function archive(item) {
const previous = items.slice();
items = items.filter(i => i.id !== item.id);
render();
let undone = false;
showToast(`"${item.name}" archived`, {
action: { label: 'Undo', onClick: () => { undone = true; items = previous; render(); } },
duration: 7000,
onDismiss: () => { if (!undone) api.commitArchive(item.id); }
});
}
The user gets the speed of "click and it happens" plus the safety of "you have 7 seconds to undo."
A delete that doesn't actually remove the data — instead moves it to a recoverable state for some window (30 days, indefinitely, until storage cleanup).
When it applies: account-level data the user might want back later; emails, documents, files. Common in B2B SaaS.
Implementation pattern:
// Soft delete
async function softDelete(item) {
await api.update(item.id, { deletedAt: new Date(), deletedBy: currentUser.id });
}
// In default queries
const visibleItems = items.filter(i => !i.deletedAt);
// Recovery view
const trashedItems = items.filter(i => i.deletedAt && daysAgo(i.deletedAt) < 30);
async function restore(item) {
await api.update(item.id, { deletedAt: null, deletedBy: null });
}
The strongest reversibility: every state of the object is preserved; the user can return to any prior state.
When it applies: documents, code, designs, configurations — anything users edit over time and might want to revert.
Implementation pattern:
Google Docs, Notion, Figma, GitHub all implement this. The user never fears editing because they can always restore.
Gmail's pattern: an action that appears committed actually defers for a few seconds, allowing cancellation in that window.
When it applies: actions that the user often regrets immediately after triggering — sending an email, posting publicly, sending a message.
Implementation pattern:
The user feels they sent it; the system just defers commitment briefly. The defer window is short (5–30 seconds) — long enough to catch reflexive "wait!" moments, short enough not to delay genuine sends.
| Action type | Recommended reversibility |
|---|---|
| Text/edit/format change | Synchronous undo (Cmd-Z) |
| Archive / soft delete one item | Toast-with-undo |
| Hard delete / account changes | Soft delete + recovery view |
| Document edits | Version history + Cmd-Z |
| Send / publish / post | Undo-send window |
| Bulk destructive | Soft delete + bulk-restore in trash |
Some actions genuinely can't be reversed at the data layer:
For these, lean on the next-strongest forgiveness levels: structural prevention (good affordances), confirmation (deliberate intent), and warnings.
The "Undo send" pattern bridges this for some communications: the external action is still irreversible, but the system delays it long enough for the user to catch second thoughts.
For toast-with-undo: 5–10 seconds is the typical range.
For soft delete: 7–30 days is typical.
A reversibility mechanism that users don't know exists doesn't help. Patterns:
If users are filing tickets to recover data they could have restored themselves, the recovery affordance isn't visible enough.
forgiveness (parent).forgiveness-confirmation-and-prevention — the alternative when reversibility isn't possible.feedback-loop — toast-with-undo is feedback that doubles as reversibility.factor-of-safety (process) — engineering analog of "design with margin so errors are recoverable."