0
# Navigation and Interaction
1
2
Extensions that enhance cursor movement, gap navigation, and user interaction patterns within the editor.
3
4
## Capabilities
5
6
### Gap Cursor Extension
7
8
Enables cursor placement in gaps between block nodes where no content normally exists, improving navigation between structural elements.
9
10
```typescript { .api }
11
/**
12
* Gap cursor extension for cursor placement between block nodes
13
*/
14
const Gapcursor: Extension;
15
16
declare module '@tiptap/core' {
17
interface NodeConfig<Options, Storage> {
18
/** Configure whether this node type allows gap cursor placement */
19
allowGapCursor?: boolean | null | ((this: {
20
name: string;
21
options: Options;
22
storage: Storage;
23
parent: ParentConfig<NodeConfig<Options>>['allowGapCursor'];
24
}) => boolean | null);
25
}
26
}
27
```
28
29
**Usage Examples:**
30
31
```typescript
32
import { Gapcursor } from "@tiptap/extensions/gap-cursor";
33
34
// Enable gap cursor
35
const editor = new Editor({
36
extensions: [
37
Gapcursor,
38
],
39
});
40
41
// Configure nodes to allow/disallow gap cursor
42
import { Node } from "@tiptap/core";
43
44
const CustomBlock = Node.create({
45
name: 'customBlock',
46
47
addOptions() {
48
return {
49
allowGapCursor: true, // Allow gap cursor around this node
50
};
51
},
52
53
// Node definition...
54
});
55
56
// Dynamic allowGapCursor configuration
57
const ConditionalNode = Node.create({
58
name: 'conditionalNode',
59
60
addOptions() {
61
return {
62
allowGapCursor: function() {
63
// Custom logic to determine gap cursor allowance
64
return this.options.someCondition === true;
65
},
66
};
67
},
68
});
69
```
70
71
**Gap Cursor Behavior:**
72
- Allows cursor placement in gaps between block elements
73
- Useful for navigating between complex block structures
74
- Integrates with ProseMirror's gap cursor plugin
75
- Node types can opt-in or opt-out of gap cursor behavior
76
- Provides better UX for structured document editing
77
78
### Selection Extension
79
80
Provides custom styling for text selections when the editor is not focused, enhancing visual feedback for users.
81
82
```typescript { .api }
83
/**
84
* Selection extension for custom selection styling when unfocused
85
*/
86
const Selection: Extension<SelectionOptions> & {
87
/** Default export variant */
88
default: Extension<SelectionOptions>;
89
};
90
91
type SelectionOptions = {
92
/** CSS class name applied to selected text (default: 'selection') */
93
className: string;
94
}
95
```
96
97
**Usage Examples:**
98
99
```typescript
100
import { Selection } from "@tiptap/extensions/selection";
101
102
// Basic selection styling
103
const editor = new Editor({
104
extensions: [
105
Selection.configure({
106
className: 'unfocused-selection',
107
}),
108
],
109
});
110
111
// Using with CSS for visual styling
112
const styledEditor = new Editor({
113
extensions: [
114
Selection.configure({
115
className: 'custom-highlight',
116
}),
117
],
118
});
119
120
// CSS to style the selection
121
/*
122
.custom-highlight {
123
background-color: rgba(0, 123, 255, 0.3);
124
border-radius: 2px;
125
}
126
*/
127
```
128
129
**Selection Features:**
130
- **Unfocused Only**: Only shows custom selection when editor loses focus
131
- **Text Selection Only**: Ignores empty selections and node selections
132
- **Drag Awareness**: Hides during drag and drop operations
133
- **Automatic Cleanup**: Removes styling when editor regains focus
134
- **CSS Integration**: Works with standard CSS for visual customization
135
136
### Interaction Patterns
137
138
Both extensions enhance the user interaction model:
139
140
**Gap Cursor Interaction:**
141
- Click between blocks to position cursor in gaps
142
- Keyboard navigation through document structure
143
- Visual feedback for valid gap cursor positions
144
- Enhanced accessibility for screen readers
145
146
**Selection Interaction:**
147
- Maintains visual selection state when editor loses focus
148
- Provides clear indication of selected content
149
- Supports multi-range selections
150
- Compatible with browser native selection APIs
151
152
```typescript
153
// Combined usage for enhanced navigation
154
import { Gapcursor, Selection } from "@tiptap/extensions";
155
156
const editor = new Editor({
157
extensions: [
158
Gapcursor, // Enable gap navigation
159
Selection.configure({
160
className: 'persistent-selection', // Show selections when unfocused
161
}),
162
],
163
});
164
165
// Enhanced interaction with both extensions
166
editor.on('focus', () => {
167
console.log('Editor focused - selection styling removed');
168
});
169
170
editor.on('blur', () => {
171
console.log('Editor blurred - selection styling applied');
172
});
173
```