or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Slate Hyperscript

1

2

Slate Hyperscript provides a hyperscript helper for creating Slate documents with JSX-like syntax. It enables developers to programmatically generate Slate editor content using a familiar JSX-style API, making it easier to create complex document structures, test Slate-based editors, and work with Slate's data model.

3

4

## Package Information

5

6

- **Package Name**: slate-hyperscript

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install slate-hyperscript`

10

11

## Core Imports

12

13

```typescript

14

import {

15

jsx,

16

createHyperscript,

17

createEditor,

18

createText,

19

HyperscriptCreators,

20

HyperscriptShorthands,

21

Token,

22

AnchorToken,

23

FocusToken,

24

addAnchorToken,

25

addFocusToken,

26

getAnchorOffset,

27

getFocusOffset

28

} from "slate-hyperscript";

29

```

30

31

For CommonJS:

32

33

```javascript

34

const {

35

jsx,

36

createHyperscript,

37

createEditor,

38

createText,

39

HyperscriptCreators,

40

HyperscriptShorthands,

41

Token,

42

AnchorToken,

43

FocusToken,

44

addAnchorToken,

45

addFocusToken,

46

getAnchorOffset,

47

getFocusOffset

48

} = require("slate-hyperscript");

49

```

50

51

## Basic Usage

52

53

```typescript

54

/** @jsx jsx */

55

import { jsx } from "slate-hyperscript";

56

57

// Create a simple editor with text content

58

const editor = (

59

<editor>

60

<element>

61

Hello <text bold>world</text>!

62

</element>

63

</editor>

64

);

65

66

// Create elements with selections

67

const editorWithSelection = (

68

<editor>

69

<element>

70

w<anchor />or<focus />d

71

</element>

72

</editor>

73

);

74

75

// Create nested elements

76

const nestedEditor = (

77

<editor>

78

<element type="paragraph">

79

<element type="bold">Bold text</element>

80

Regular text

81

</element>

82

</editor>

83

);

84

```

85

86

## Architecture

87

88

Slate Hyperscript is built around several key components:

89

90

- **JSX Factory**: The main `jsx` function that processes JSX elements into Slate objects

91

- **Creator Functions**: Specialized functions for creating different Slate node types (used internally by JSX)

92

- **Token System**: Anchor and focus tokens for precise selection positioning within JSX

93

- **Hyperscript Factory**: Customizable factory for creating domain-specific hyperscript functions

94

95

## Capabilities

96

97

### Default JSX Factory

98

99

The pre-configured hyperscript function that creates Slate objects from JSX elements.

100

101

```typescript { .api }

102

/**

103

* The default hyperscript factory that ships with Slate, without custom tags.

104

*/

105

const jsx: <S extends string>(

106

tagName: S,

107

attributes?: Object,

108

...children: any[]

109

) => any;

110

```

111

112

**Usage Example:**

113

114

```typescript

115

/** @jsx jsx */

116

import { jsx } from "slate-hyperscript";

117

118

// Basic element creation

119

const element = <element>Hello world</element>;

120

121

// Text with formatting

122

const formattedText = <text bold italic>Important text</text>;

123

124

// Complete editor

125

const editor = (

126

<editor>

127

<element>Content goes here</element>

128

</editor>

129

);

130

```

131

132

### Custom Hyperscript Creation

133

134

Factory function for creating custom hyperscript functions with specialized creators and element shortcuts.

135

136

```typescript { .api }

137

/**

138

* Create a Slate hyperscript function with custom options

139

* @param options - Configuration object

140

* @returns Custom hyperscript function

141

*/

142

function createHyperscript(options?: {

143

creators?: HyperscriptCreators;

144

elements?: HyperscriptShorthands;

145

}): <S extends string>(

146

tagName: S,

147

attributes?: Object,

148

...children: any[]

149

) => any;

150

151

/**

152

* Dictionary of creator functions keyed by tag name

153

*/

154

type HyperscriptCreators<T = any> = Record<

155

string,

156

(tagName: string, attributes: { [key: string]: any }, children: any[]) => T

157

>;

158

159

/**

160

* Dictionary of properties applied to specific element types, keyed by tag name

161

*/

162

type HyperscriptShorthands = Record<string, Record<string, any>>;

163

```

164

165

**Usage Example:**

166

167

```typescript

168

import { createHyperscript } from "slate-hyperscript";

169

170

// Create hyperscript with custom element shortcuts

171

const jsx = createHyperscript({

172

elements: {

173

paragraph: { type: "paragraph" },

174

heading: { type: "heading", level: 1 },

175

},

176

});

177

178

// Now you can use custom tags

179

const content = (

180

<editor>

181

<heading>My Title</heading>

182

<paragraph>Some content</paragraph>

183

</editor>

184

);

185

```

186

187

### Utility Functions

188

189

Higher-order functions for creating specific Slate objects outside of JSX context.

190

191

```typescript { .api }

192

/**

193

* Create a top-level Editor object creator

194

* @param makeEditor - Factory function that creates a base editor instance

195

* @returns Creator function for editors

196

*/

197

const createEditor: (makeEditor: () => Editor) => (

198

tagName: string,

199

attributes: { [key: string]: any },

200

children: any[]

201

) => Editor;

202

203

/**

204

* Create a Text object creator

205

* @param tagName - The tag name (typically "text")

206

* @param attributes - Text formatting attributes (bold, italic, etc.)

207

* @param children - Text content

208

* @returns Slate Text node

209

*/

210

function createText(

211

tagName: string,

212

attributes: { [key: string]: any },

213

children: any[]

214

): Text;

215

```

216

217

**Usage Example:**

218

219

```typescript

220

import { createText, createEditor } from "slate-hyperscript";

221

import { createEditor as makeEditor } from "slate";

222

223

// Create text node directly

224

const textNode = createText("text", { bold: true }, ["Hello world"]);

225

226

// Create custom editor creator

227

const myCreateEditor = createEditor(makeEditor);

228

```

229

230

### Selection Token System

231

232

Advanced token system for programmatic selection handling and token manipulation.

233

234

```typescript { .api }

235

/**

236

* Add an anchor token to the end of a text node

237

* @param text - Text node to add anchor token to

238

* @param token - Anchor token to add

239

*/

240

function addAnchorToken(text: Text, token: AnchorToken): void;

241

242

/**

243

* Get the offset if a text node has an associated anchor token

244

* @param text - Text node to check

245

* @returns Tuple of offset and token, or undefined if no anchor token

246

*/

247

function getAnchorOffset(text: Text): [number, AnchorToken] | undefined;

248

249

/**

250

* Add a focus token to the end of a text node

251

* @param text - Text node to add focus token to

252

* @param token - Focus token to add

253

*/

254

function addFocusToken(text: Text, token: FocusToken): void;

255

256

/**

257

* Get the offset if a text node has an associated focus token

258

* @param text - Text node to check

259

* @returns Tuple of offset and token, or undefined if no focus token

260

*/

261

function getFocusOffset(text: Text): [number, FocusToken] | undefined;

262

```

263

264

**Usage Example:**

265

266

```typescript

267

import { addAnchorToken, AnchorToken, createText } from "slate-hyperscript";

268

269

// Create a text node and programmatically add selection tokens

270

const textNode = createText("text", {}, ["Hello world"]);

271

const anchorToken = new AnchorToken({ offset: 5 });

272

addAnchorToken(textNode, anchorToken);

273

```

274

275

## JSX Element Types

276

277

The following JSX elements are available by default when using the `jsx` factory:

278

279

### Core Elements

280

281

```typescript { .api }

282

// Basic document structure

283

<editor>...</editor> // Creates Editor with content and optional selection

284

<element>...</element> // Creates Element nodes with children

285

<text>...</text> // Creates Text nodes with formatting

286

<fragment>...</fragment> // Creates arrays of Descendant nodes

287

288

// Selection positioning

289

<anchor /> // Marks selection anchor point

290

<focus /> // Marks selection focus point

291

<cursor /> // Marks collapsed selection point

292

<selection>...</selection> // Creates explicit Selection objects

293

```

294

295

**Usage Examples:**

296

297

```typescript

298

/** @jsx jsx */

299

import { jsx } from "slate-hyperscript";

300

301

// Basic elements

302

const element = <element type="paragraph">Hello world</element>;

303

const textNode = <text bold italic>Formatted text</text>;

304

305

// Document fragments

306

const fragment = (

307

<fragment>

308

<element>First paragraph</element>

309

<element>Second paragraph</element>

310

</fragment>

311

);

312

313

// Selections in text

314

const withSelection = (

315

<editor>

316

<element>

317

Hello <anchor />beautiful<focus /> world

318

</element>

319

</editor>

320

);

321

322

// Collapsed selection (cursor)

323

const withCursor = (

324

<editor>

325

<element>

326

Hello <cursor />world

327

</element>

328

</editor>

329

);

330

331

// Explicit selection object

332

const selection = (

333

<selection>

334

<anchor path={[0, 0]} offset={5} />

335

<focus path={[0, 0]} offset={14} />

336

</selection>

337

);

338

```

339

340

## Types

341

342

```typescript { .api }

343

/**

344

* Base class for all selection tokens

345

*/

346

class Token {}

347

348

/**

349

* Represents selection anchor points

350

*/

351

class AnchorToken extends Token {

352

offset?: number;

353

path?: Path;

354

355

constructor(props?: {

356

offset?: number;

357

path?: Path;

358

});

359

}

360

361

/**

362

* Represents selection focus points

363

*/

364

class FocusToken extends Token {

365

offset?: number;

366

path?: Path;

367

368

constructor(props?: {

369

offset?: number;

370

path?: Path;

371

});

372

}

373

```

374

375

## Error Handling

376

377

Common errors you may encounter:

378

379

- **Missing Creator**: `"No hyperscript creator found for tag: <tagName>"` - occurs when using undefined JSX tag names

380

- **Invalid Selection Setup**: `"The <selection> hyperscript tag must have an <anchor> tag as a child with \`path\` and \`offset\` attributes defined."` - occurs when selection tags are missing required anchor/focus children with proper attributes

381

- **Text Content Validation**: `"The <text> hyperscript tag can only contain text content as children."` - occurs when `<text>` tags contain non-text children like elements

382

- **Incomplete Selection Ranges**: `"Slate hyperscript ranges must have both \`<anchor />\` and \`<focus />\` defined if one is defined, but you only defined \`<anchor />\`. For collapsed selections, use \`<cursor />\` instead."` - occurs when only one selection point is defined

383

- **Custom Element Configuration**: `"Properties specified for a hyperscript shorthand should be an object, but for the custom element <tagName> tag you passed: [value]"` - occurs when element shortcuts in `createHyperscript` options are not objects

384

385

## JSX Setup

386

387

To use JSX syntax with slate-hyperscript, configure your TypeScript/Babel setup:

388

389

**TypeScript (tsconfig.json):**

390

```json

391

{

392

"compilerOptions": {

393

"jsx": "react",

394

"jsxFactory": "jsx"

395

}

396

}

397

```

398

399

**Per-file pragma:**

400

```typescript

401

/** @jsx jsx */

402

import { jsx } from "slate-hyperscript";

403

```

404

405

## Dependencies

406

407

- **slate**: Peer dependency (>=0.114.3) providing core types `Element`, `Text`, `Range`, `Editor`, `Descendant`, `Path`, etc.