diff options
Diffstat (limited to 'docs/actions.md')
| -rw-r--r-- | docs/actions.md | 170 |
1 files changed, 85 insertions, 85 deletions
diff --git a/docs/actions.md b/docs/actions.md index 44c2153f..3d001e86 100644 --- a/docs/actions.md +++ b/docs/actions.md @@ -1,85 +1,85 @@ -# Actions System - -Actions are the trigger layer for user-initiated operations. They connect keyboard shortcuts, UI buttons, and context menus to editor functionality. - -## Adding a New Action - -### 1. Define the action — `src/lib/actions/definitions.ts` - -Add an entry to the `ACTIONS` object: - -```typescript -"my-action": { - description: "What it does", - category: "editing", // playback | navigation | editing | selection | history | timeline | controls - defaultShortcuts: ["ctrl+m"], // optional - args: { someValue: "number" }, // optional, only if it takes args -}, -``` - -**If your shortcut uses a special key** (not a letter/digit), check `getPressedKey` in `src/stores/keybindings-store.ts` and add a case if it's missing: - -```typescript -if (key === "escape") return "escape"; -``` - -**If your action has a `defaultShortcuts`**, also add a keybindings migration so existing users get it (keybindings are persisted in localStorage — new defaults only apply to fresh installs): - -1. Create `src/stores/keybindings/migrations/vN-to-vN+1.ts`: - -```typescript -export function vNToVN1({ state }: { state: unknown }): unknown { - const s = state as { keybindings: Record<string, string>; isCustomized: boolean }; - const keybindings = { ...s.keybindings }; - if (!keybindings["my-key"]) { - keybindings["my-key"] = "my-action"; - } - return { ...s, keybindings }; -} -``` - -2. Register it in `src/stores/keybindings/migrations/index.ts` and bump `CURRENT_VERSION`. - -### 2. Register the handler — `src/hooks/actions/use-editor-actions.ts` - -```typescript -useActionHandler( - "my-action", - () => { - editor.timeline.doSomething(); - }, - undefined, // isActive: MutableRefObject<boolean> | boolean | undefined -); -``` - -### 3. Register arg types (if needed) — `src/lib/actions/types.ts` - -Only required if your action accepts arguments: - -```typescript -export type TActionArgsMap = { - // ...existing actions... - "my-action": { someValue: number } | undefined; // | undefined = optional args -}; -``` - -## Invoking Actions - -Use `invokeAction` for any user-triggered operation (buttons, context menus, etc.): - -```typescript -import { invokeAction } from "@/lib/actions"; - -invokeAction("my-action"); -invokeAction("seek-forward", { seconds: 5 }); -``` - -Avoid calling `editor.xxx()` directly from UI components — that bypasses the action layer (toasts, validation feedback, keybinding support). - -## The `isActive` parameter - -The third argument to `useActionHandler` controls when the handler is active: - -- `undefined` — always active -- `true` / `false` — statically enabled/disabled -- `MutableRefObject<boolean>` — reactive, toggled at runtime (e.g. only active when a panel is focused) +# Actions System
+
+Actions are the trigger layer for user-initiated operations. They connect keyboard shortcuts, UI buttons, and context menus to editor functionality.
+
+## Adding a New Action
+
+### 1. Define the action — `src/lib/actions/definitions.ts`
+
+Add an entry to the `ACTIONS` object:
+
+```typescript
+"my-action": {
+ description: "What it does",
+ category: "editing", // playback | navigation | editing | selection | history | timeline | controls
+ defaultShortcuts: ["ctrl+m"], // optional
+ args: { someValue: "number" }, // optional, only if it takes args
+},
+```
+
+**If your shortcut uses a special key** (not a letter/digit), check `getPressedKey` in `src/stores/keybindings-store.ts` and add a case if it's missing:
+
+```typescript
+if (key === "escape") return "escape";
+```
+
+**If your action has a `defaultShortcuts`**, also add a keybindings migration so existing users get it (keybindings are persisted in localStorage — new defaults only apply to fresh installs):
+
+1. Create `src/stores/keybindings/migrations/vN-to-vN+1.ts`:
+
+```typescript
+export function vNToVN1({ state }: { state: unknown }): unknown {
+ const s = state as { keybindings: Record<string, string>; isCustomized: boolean };
+ const keybindings = { ...s.keybindings };
+ if (!keybindings["my-key"]) {
+ keybindings["my-key"] = "my-action";
+ }
+ return { ...s, keybindings };
+}
+```
+
+2. Register it in `src/stores/keybindings/migrations/index.ts` and bump `CURRENT_VERSION`.
+
+### 2. Register the handler — `src/hooks/actions/use-editor-actions.ts`
+
+```typescript
+useActionHandler(
+ "my-action",
+ () => {
+ editor.timeline.doSomething();
+ },
+ undefined, // isActive: MutableRefObject<boolean> | boolean | undefined
+);
+```
+
+### 3. Register arg types (if needed) — `src/lib/actions/types.ts`
+
+Only required if your action accepts arguments:
+
+```typescript
+export type TActionArgsMap = {
+ // ...existing actions...
+ "my-action": { someValue: number } | undefined; // | undefined = optional args
+};
+```
+
+## Invoking Actions
+
+Use `invokeAction` for any user-triggered operation (buttons, context menus, etc.):
+
+```typescript
+import { invokeAction } from "@/lib/actions";
+
+invokeAction("my-action");
+invokeAction("seek-forward", { seconds: 5 });
+```
+
+Avoid calling `editor.xxx()` directly from UI components — that bypasses the action layer (toasts, validation feedback, keybinding support).
+
+## The `isActive` parameter
+
+The third argument to `useActionHandler` controls when the handler is active:
+
+- `undefined` — always active
+- `true` / `false` — statically enabled/disabled
+- `MutableRefObject<boolean>` — reactive, toggled at runtime (e.g. only active when a panel is focused)
|
