or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Tiptap Focus Extension

1

2

The Focus extension allows you to add CSS classes to focused nodes in a Tiptap editor, providing visual focus indicators that enhance user experience and accessibility. It operates as a ProseMirror plugin that decorates nodes based on cursor position, offering three different focus modes for various use cases.

3

4

## Package Information

5

6

- **Package Name**: @tiptap/extensions/focus

7

- **Package Type**: npm (TypeScript extension)

8

- **Language**: TypeScript

9

- **Installation**: `npm install @tiptap/extensions`

10

11

## Core Imports

12

13

```typescript

14

import { Focus, FocusOptions } from "@tiptap/extensions";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { Focus, FocusOptions } = require("@tiptap/extensions");

21

```

22

23

Sub-path imports (also supported):

24

25

```typescript

26

import { Focus, FocusOptions } from "@tiptap/extensions/focus";

27

```

28

29

## Basic Usage

30

31

```typescript

32

import { Editor } from "@tiptap/core";

33

import { Focus } from "@tiptap/extensions";

34

35

// Basic usage with default options

36

const editor = new Editor({

37

extensions: [

38

Focus,

39

// ... other extensions

40

],

41

content: "<p>Your content here</p>",

42

});

43

44

// Custom configuration

45

const editor = new Editor({

46

extensions: [

47

Focus.configure({

48

className: 'is-focused',

49

mode: 'deepest',

50

}),

51

// ... other extensions

52

],

53

content: "<p>Your content here</p>",

54

});

55

```

56

57

## Architecture

58

59

The Focus extension integrates with Tiptap's extension system and uses ProseMirror's decoration API to efficiently add CSS classes to DOM elements without re-rendering content. Key components:

60

61

- **Extension Class**: Extends Tiptap's base Extension class with focus-specific configuration

62

- **ProseMirror Plugin**: Implements the actual focus detection and decoration logic

63

- **Decoration System**: Uses ProseMirror's DecorationSet for performant DOM manipulation

64

- **Focus Detection**: Analyzes document structure and cursor position to determine focused nodes

65

66

## Capabilities

67

68

### Focus Extension

69

70

Creates a Tiptap extension that adds CSS classes to focused nodes based on cursor position.

71

72

```typescript { .api }

73

import { Extension } from "@tiptap/core";

74

75

/**

76

* Focus extension that adds CSS classes to focused nodes

77

* Extends Tiptap's base Extension class with FocusOptions configuration

78

*/

79

const Focus: Extension<FocusOptions>;

80

```

81

82

### Focus Configuration

83

84

Configures the Focus extension with custom options.

85

86

```typescript { .api }

87

/**

88

* Configure the Focus extension with custom options

89

* @param options - Configuration options for focus behavior

90

* @returns Configured Focus extension instance

91

*/

92

Focus.configure(options: Partial<FocusOptions>): Extension<FocusOptions>;

93

```

94

95

### Focus Mode: All

96

97

Marks all nodes in the selection path as focused (default behavior).

98

99

```typescript

100

// Configuration for 'all' mode

101

Focus.configure({

102

mode: 'all',

103

className: 'has-focus'

104

})

105

```

106

107

### Focus Mode: Deepest

108

109

Marks only the deepest (innermost) node in the selection as focused.

110

111

```typescript

112

// Configuration for 'deepest' mode

113

Focus.configure({

114

mode: 'deepest',

115

className: 'has-focus'

116

})

117

```

118

119

### Focus Mode: Shallowest

120

121

Marks only the shallowest (outermost) node in the selection as focused.

122

123

```typescript

124

// Configuration for 'shallowest' mode

125

Focus.configure({

126

mode: 'shallowest',

127

className: 'has-focus'

128

})

129

```

130

131

## Types

132

133

```typescript { .api }

134

/**

135

* Configuration options for the Focus extension

136

*/

137

interface FocusOptions {

138

/**

139

* The CSS class name that should be added to the focused node

140

* @default 'has-focus'

141

* @example 'is-focused'

142

*/

143

className: string;

144

145

/**

146

* The mode by which the focused node is determined

147

* - 'all': All nodes in the selection path are marked as focused

148

* - 'deepest': Only the innermost node is marked as focused

149

* - 'shallowest': Only the outermost node is marked as focused

150

* @default 'all'

151

*/

152

mode: 'all' | 'deepest' | 'shallowest';

153

}

154

```

155

156

## Usage Examples

157

158

### Custom CSS Class

159

160

```typescript

161

import { Editor } from "@tiptap/core";

162

import { Focus } from "@tiptap/extensions";

163

164

const editor = new Editor({

165

extensions: [

166

Focus.configure({

167

className: 'editor-focused-node'

168

})

169

],

170

content: '<p>Your content here</p>',

171

});

172

```

173

174

### Deepest Node Focus

175

176

```typescript

177

// Only highlight the innermost focused element

178

const editor = new Editor({

179

extensions: [

180

Focus.configure({

181

mode: 'deepest',

182

className: 'deeply-focused'

183

})

184

],

185

content: '<p>Your content here</p>',

186

});

187

```

188

189

### Accessibility Enhancement

190

191

```typescript

192

// Use ARIA-friendly class names for screen readers

193

const editor = new Editor({

194

extensions: [

195

Focus.configure({

196

className: 'aria-current-element',

197

mode: 'deepest'

198

})

199

],

200

content: '<p>Your content here</p>',

201

});

202

```

203

204

### CSS Styling

205

206

```css

207

/* Style focused nodes */

208

.has-focus {

209

outline: 2px solid #007acc;

210

outline-offset: 2px;

211

}

212

213

/* Different styles for different focus modes */

214

.deeply-focused {

215

background-color: rgba(0, 122, 204, 0.1);

216

border-radius: 4px;

217

}

218

219

.aria-current-element {

220

box-shadow: 0 0 0 2px #007acc;

221

}

222

```

223

224

## Integration Requirements

225

226

The Focus extension requires:

227

228

- **Tiptap Core**: `@tiptap/core` for base Extension class

229

- **ProseMirror State**: `@tiptap/pm/state` for Plugin and PluginKey

230

- **ProseMirror View**: `@tiptap/pm/view` for Decoration and DecorationSet

231

- **Editor Instance**: Must be used within a Tiptap Editor configuration

232

233

## Behavior Notes

234

235

- Focus indicators only appear when the editor is both editable and focused

236

- The extension automatically handles cursor movement and selection changes

237

- CSS classes are applied and removed dynamically as focus changes

238

- Performance is optimized through ProseMirror's decoration system

239

- Works with all standard Tiptap nodes and marks