diff --git a/src/myfasthtml/assets/README.md b/docs/Keyboard Support.md
similarity index 85%
rename from src/myfasthtml/assets/README.md
rename to docs/Keyboard Support.md
index 2bb7130..11a5802 100644
--- a/src/myfasthtml/assets/README.md
+++ b/docs/Keyboard Support.md
@@ -187,6 +187,7 @@ All other `hx-*` attributes are supported and will be converted to the appropria
The library automatically adds these parameters to every request:
- `combination` - The combination that triggered the action (e.g., "Ctrl+S")
- `has_focus` - Boolean indicating if the element had focus
+- `is_inside` - Boolean indicating if the focus is inside the element (element itself or any child)
Example final request:
```javascript
@@ -196,7 +197,8 @@ htmx.ajax('POST', '/save-url', {
values: {
extra: "data", // from hx-vals
combination: "Ctrl+S", // automatic
- has_focus: true // automatic
+ has_focus: true, // automatic
+ is_inside: true // automatic
}
})
```
@@ -262,6 +264,55 @@ f"add_keyboard_support('modal', '{json.dumps(modal_combinations)}')"
f"add_keyboard_support('editor', '{json.dumps(editor_combinations)}')"
```
+### Removing Keyboard Support
+
+When you no longer need keyboard support for an element:
+
+```python
+# Remove keyboard support
+f"remove_keyboard_support('{element_id}')"
+```
+
+**Behavior**:
+- Removes the element from the keyboard registry
+- If this was the last element, automatically detaches global event listeners
+- Cleans up all associated state (timeouts, snapshots, etc.)
+- Other elements continue to work normally
+
+**Example**:
+```javascript
+// Add support
+add_keyboard_support('modal', '{"esc": {"hx-post": "/close"}}');
+
+// Later, remove support
+remove_keyboard_support('modal');
+// If no other elements remain, keyboard listeners are completely removed
+```
+
+## API Reference
+
+### add_keyboard_support(elementId, combinationsJson)
+
+Adds keyboard support to an element.
+
+**Parameters**:
+- `elementId` (string): ID of the HTML element
+- `combinationsJson` (string): JSON string of combinations with HTMX configs
+
+**Returns**: void
+
+### remove_keyboard_support(elementId)
+
+Removes keyboard support from an element.
+
+**Parameters**:
+- `elementId` (string): ID of the HTML element
+
+**Returns**: void
+
+**Side effects**:
+- If last element: detaches global event listeners and cleans up all state
+
## Technical Details
### Trie-based Matching
@@ -277,7 +328,7 @@ The library uses a prefix tree (trie) data structure:
Configuration objects are mapped to htmx.ajax() calls:
- `hx-*` attributes are converted to camelCase parameters
- HTTP method is extracted from `hx-post`, `hx-get`, etc.
-- `combination` and `has_focus` are automatically added to values
+- `combination`, `has_focus`, and `is_inside` are automatically added to values
- All standard HTMX options are supported
### Key Normalization
diff --git a/docs/Mouse Support.md b/docs/Mouse Support.md
new file mode 100644
index 0000000..d476659
--- /dev/null
+++ b/docs/Mouse Support.md
@@ -0,0 +1,439 @@
+# Mouse Support - Documentation
+
+## Overview
+
+The mouse support library provides keyboard-like binding capabilities for mouse actions. It supports simple clicks, modified clicks (with Ctrl/Shift/Alt), and sequences of clicks with smart timeout logic.
+
+## Features
+
+### Supported Mouse Actions
+
+**Basic Actions**:
+- `click` - Left click
+- `right_click` (or `rclick`) - Right click (contextmenu)
+
+**Modified Actions**:
+- `ctrl+click` (or `ctrl+rclick`) - Ctrl+Click (or Cmd+Click on Mac)
+- `shift+click` (or `shift+rclick`) - Shift+Click
+- `alt+click` (or `alt+rclick`) - Alt+Click
+- `ctrl+shift+click` - Multiple modifiers
+- Any combination of modifiers
+
+**Sequences**:
+- `click right_click` (or `click rclick`) - Click then right-click within 500ms
+- `click click` - Double click sequence
+- `ctrl+click click` - Ctrl+click then normal click
+- Any sequence of actions
+
+**Note**: `rclick` is an alias for `right_click` and can be used interchangeably.
+
+### Smart Timeout Logic
+
+Same as keyboard support:
+- If **any element** has a longer sequence possible, **all matching elements wait**
+- Timeout is 500ms between actions
+- Immediate trigger if no longer sequences exist
+
+### Multiple Element Support
+
+Multiple elements can listen to the same mouse action and all will trigger simultaneously.
+
+## Configuration Format
+
+Uses HTMX configuration objects (same as keyboard support):
+
+```javascript
+const combinations = {
+ "click": {
+ "hx-post": "/handle-click",
+ "hx-target": "#result"
+ },
+ "ctrl+click": {
+ "hx-post": "/handle-ctrl-click",
+ "hx-swap": "innerHTML"
+ },
+ "rclick": { // Alias for right_click
+ "hx-post": "/context-menu"
+ },
+ "click rclick": { // Can use rclick in sequences too
+ "hx-post": "/sequence-action",
+ "hx-vals": {"type": "sequence"}
+ }
+};
+
+add_mouse_support('my-element', JSON.stringify(combinations));
+```
+
+## API Reference
+
+### add_mouse_support(elementId, combinationsJson)
+
+Adds mouse support to an element.
+
+**Parameters**:
+- `elementId` (string): ID of the HTML element
+- `combinationsJson` (string): JSON string of combinations with HTMX configs
+
+**Returns**: void
+
+**Example**:
+```javascript
+add_mouse_support('button1', JSON.stringify({
+ "click": {"hx-post": "/click"},
+ "ctrl+click": {"hx-post": "/ctrl-click"}
+}));
+```
+
+### remove_mouse_support(elementId)
+
+Removes mouse support from an element.
+
+**Parameters**:
+- `elementId` (string): ID of the HTML element
+
+**Returns**: void
+
+**Side effects**:
+- If last element: detaches global event listeners and cleans up all state
+
+**Example**:
+```javascript
+remove_mouse_support('button1');
+```
+
+## Automatic Parameters
+
+The library automatically adds these parameters to every HTMX request:
+- `combination` - The mouse combination that triggered the action (e.g., "ctrl+click")
+- `has_focus` - Boolean indicating if the element had focus when clicked
+- `is_inside` - Boolean indicating if the click was inside the element
+ - For `click`: `true` if clicked inside element, `false` if clicked outside
+ - For `right_click`: always `true` (only triggers when clicking on element)
+- `has_focus` - Boolean indicating if the element had focus when the action triggered
+- `clicked_inside` - Boolean indicating if the click was inside the element or outside
+
+### Parameter Details
+
+**`has_focus`**:
+- `true` if the registered element currently has focus
+- `false` otherwise
+- Useful for knowing if the element was the active element
+
+**`clicked_inside`**:
+- For `click` actions: `true` if clicked on/inside the element, `false` if clicked outside
+- For `right_click` actions: always `true` (since right-click only triggers on the element)
+- Useful for "click outside to close" logic
+
+**Example values sent**:
+```javascript
+// User clicks inside a modal
+{
+ combination: "click",
+ has_focus: true,
+ clicked_inside: true
+}
+
+// User clicks outside the modal (modal still gets triggered because click is global)
+{
+ combination: "click",
+ has_focus: false,
+ clicked_inside: false // Perfect for closing the modal!
+}
+
+// User right-clicks on an item
+{
+ combination: "right_click",
+ has_focus: false,
+ clicked_inside: true // Always true for right_click
+}
+```
+
+## Python Integration
+
+### Basic Usage
+
+```python
+combinations = {
+ "click": {
+ "hx-post": "/item/select"
+ },
+ "ctrl+click": {
+ "hx-post": "/item/select-multiple",
+ "hx-vals": json.dumps({"mode": "multi"})
+ },
+ "right_click": {
+ "hx-post": "/item/context-menu",
+ "hx-target": "#context-menu",
+ "hx-swap": "innerHTML"
+ }
+}
+
+f"add_mouse_support('{element_id}', '{json.dumps(combinations)}')"
+```
+
+### Sequences
+
+```python
+combinations = {
+ "click": {
+ "hx-post": "/single-click"
+ },
+ "click click": {
+ "hx-post": "/double-click-sequence"
+ },
+ "click right_click": {
+ "hx-post": "/click-then-right-click"
+ }
+}
+```
+
+### Multiple Elements
+
+```python
+# Item 1
+item1_combinations = {
+ "click": {"hx-post": f"/item/1/select"},
+ "ctrl+click": {"hx-post": f"/item/1/toggle"}
+}
+f"add_mouse_support('item-1', '{json.dumps(item1_combinations)}')"
+
+# Item 2
+item2_combinations = {
+ "click": {"hx-post": f"/item/2/select"},
+ "ctrl+click": {"hx-post": f"/item/2/toggle"}
+}
+f"add_mouse_support('item-2', '{json.dumps(item2_combinations)}')"
+```
+
+## Behavior Details
+
+### Click vs Right-Click Behavior
+
+**IMPORTANT**: The library handles `click` and `right_click` differently:
+
+**`click` (global detection)**:
+- Triggers for ALL registered elements, regardless of where you click
+- Useful for "click outside to close" functionality (modals, dropdowns, popups)
+- Example: Modal registered with `click` → clicking anywhere on the page triggers the modal's click action
+
+**`right_click` (element-specific detection)**:
+- Triggers ONLY when you right-click on (or inside) the registered element
+- Right-clicking outside the element does nothing and shows browser's context menu
+- This preserves normal browser behavior while adding custom actions on your elements
+
+**Example use case**:
+```javascript
+// Modal that closes when clicking anywhere
+add_mouse_support('modal', JSON.stringify({
+ "click": {"hx-post": "/close-modal"} // Triggers even if you click outside modal
+}));
+
+// Context menu that only appears on element
+add_mouse_support('item', JSON.stringify({
+ "right_click": {"hx-post": "/item-menu"} // Only triggers when right-clicking the item
+}));
+```
+
+### Modifier Keys (Cross-Platform)
+
+- **Windows/Linux**: `ctrl+click` uses Ctrl key
+- **Mac**: `ctrl+click` uses Cmd (⌘) key OR Ctrl key
+- This follows standard web conventions for cross-platform compatibility
+
+### Input Context Protection
+
+Mouse actions are **disabled** when clicking in input fields:
+- `` elements
+- `