## How Canvas Library Custom Functionality Works

### 1. **The Canvas Library Calls YOUR Custom Code First**

When you call `ActionDispatcher::dispatch()`, here's what happens:

```rust
// Inside canvas library (canvas/src/actions/edit.rs):
pub async fn execute_canvas_action<S: CanvasState>(
    action: CanvasAction,
    state: &mut S,
    ideal_cursor_column: &mut usize,
) -> Result<ActionResult> {
    // 1. FIRST: Canvas library calls YOUR custom handler
    if let Some(result) = state.handle_feature_action(&action, &context) {
        return Ok(ActionResult::HandledByFeature(result)); // YOUR code handled it
    }

    // 2. ONLY IF your code returns None: Canvas handles generic actions
    handle_generic_canvas_action(action, state, ideal_cursor_column).await
}
```

### 2. **Your Extension Point: `handle_feature_action`**

You add custom functionality by implementing `handle_feature_action` in your states:

```rust
// In src/state/pages/auth.rs
impl CanvasState for LoginState {
    // ... other methods ...

    fn handle_feature_action(&mut self, action: &CanvasAction, context: &ActionContext) -> Option<String> {
        match action {
            // Custom login-specific actions
            CanvasAction::Custom(action_str) if action_str == "submit_login" => {
                if self.username.is_empty() || self.password.is_empty() {
                    Some("Please fill in all required fields".to_string())
                } else {
                    // Trigger login process
                    Some(format!("Logging in user: {}", self.username))
                }
            }
            
            CanvasAction::Custom(action_str) if action_str == "clear_form" => {
                self.username.clear();
                self.password.clear();
                self.set_has_unsaved_changes(false);
                Some("Login form cleared".to_string())
            }

            // Custom behavior for standard actions
            CanvasAction::NextField => {
                // Custom validation when moving between fields
                if self.current_field == 0 && self.username.is_empty() {
                    Some("Username cannot be empty".to_string())
                } else {
                    None // Let canvas library handle the normal field movement
                }
            }

            // Let canvas library handle everything else
            _ => None,
        }
    }
}
```

### 3. **Multiple Ways to Add Custom Functionality**

#### A) **Custom Actions via Config**
```toml
# In config.toml
[keybindings.edit]
submit_login = ["ctrl+enter"]
clear_form = ["ctrl+r"]
```

#### B) **Override Standard Actions**
```rust
fn handle_feature_action(&mut self, action: &CanvasAction, context: &ActionContext) -> Option<String> {
    match action {
        CanvasAction::InsertChar('p') if self.current_field == 1 => {
            // Custom behavior when typing 'p' in password field
            Some("Password field - use secure input".to_string())
        }
        _ => None, // Let canvas handle normally
    }
}
```

#### C) **Context-Aware Logic**
```rust
fn handle_feature_action(&mut self, action: &CanvasAction, context: &ActionContext) -> Option<String> {
    match action {
        CanvasAction::MoveDown => {
            // Custom logic based on current state
            if context.current_field == 1 && context.current_input.len() < 8 {
                Some("Password should be at least 8 characters".to_string())
            } else {
                None // Normal field movement
            }
        }
        _ => None,
    }
}
```

## The Canvas Library Philosophy

**Canvas Library = Generic behavior + Your extension points**

- ✅ **Canvas handles**: Character insertion, cursor movement, field navigation, etc.
- ✅ **You handle**: Validation, submission, clearing, app-specific logic
- ✅ **You decide**: Return `Some(message)` to override, `None` to use canvas default

## Summary

You **don't communicate with the library elsewhere**. Instead:

1. **Canvas library calls your code first** via `handle_feature_action`
2. **Your code decides** whether to handle the action or let canvas handle it
3. **Canvas library handles** generic form behavior when you return `None`

