or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdcore.mdindex.mdjsx.mdmodules.md

jsx.mddocs/

0

# JSX Support

1

2

Snabbdom provides comprehensive JSX support with factory functions and TypeScript definitions for React-style development patterns.

3

4

## Capabilities

5

6

### JSX Factory Function

7

8

Creates virtual nodes from JSX syntax, supporting both HTML elements and function components.

9

10

```typescript { .api }

11

/**

12

* JSX factory function for creating virtual nodes

13

* @param tag - HTML tag name or function component

14

* @param data - Virtual node data (props, attrs, etc.)

15

* @param children - Child elements

16

* @returns Virtual node

17

*/

18

function jsx(

19

tag: string | FunctionComponent,

20

data: VNodeData | null,

21

...children: JsxVNodeChildren[]

22

): VNode;

23

24

type FunctionComponent = (

25

props: { [prop: string]: any } | null,

26

children?: VNode[]

27

) => VNode;

28

```

29

30

### Fragment Component

31

32

Creates document fragments for grouping elements without wrapper elements (experimental).

33

34

```typescript { .api }

35

/**

36

* JSX Fragment component for grouping elements

37

* @param data - Optional data object with key

38

* @param children - Child elements to group

39

* @returns Virtual node representing a fragment

40

*/

41

function Fragment(

42

data: { key?: Key } | null,

43

...children: JsxVNodeChildren[]

44

): VNode;

45

```

46

47

## TypeScript Configuration

48

49

Add the following to your `tsconfig.json`:

50

51

```json

52

{

53

"compilerOptions": {

54

"jsx": "react",

55

"jsxFactory": "jsx",

56

"jsxFragmentFactory": "Fragment"

57

}

58

}

59

```

60

61

**Usage Example:**

62

63

```typescript

64

import { Fragment, jsx, VNode, init, classModule, styleModule } from "snabbdom";

65

66

const patch = init([classModule, styleModule]);

67

68

// Simple JSX elements

69

const greeting: VNode = <h1>Hello, World!</h1>;

70

71

// Elements with props and children

72

const button: VNode = (

73

<button

74

class={{ primary: true, large: false }}

75

on={{ click: () => console.log("clicked") }}

76

>

77

Click me

78

</button>

79

);

80

81

// Complex JSX structure

82

const app: VNode = (

83

<div class="app">

84

<header>

85

<h1>My Application</h1>

86

</header>

87

<main>

88

<p>Welcome to Snabbdom with JSX!</p>

89

{button}

90

</main>

91

</div>

92

);

93

94

// JSX Fragments (experimental)

95

const fragmentExample: VNode = (

96

<>

97

<p>First paragraph</p>

98

<p>Second paragraph</p>

99

</>

100

);

101

```

102

103

## Babel Configuration

104

105

For JavaScript projects using Babel, add the following to your Babel configuration:

106

107

```json

108

{

109

"plugins": [

110

[

111

"@babel/plugin-transform-react-jsx",

112

{

113

"pragma": "jsx",

114

"pragmaFrag": "Fragment"

115

}

116

]

117

]

118

}

119

```

120

121

**Usage Example:**

122

123

```javascript

124

import { Fragment, jsx } from "snabbdom";

125

126

const component = (

127

<div>

128

<span>I was created with JSX</span>

129

</div>

130

);

131

132

const fragmentComponent = (

133

<>

134

<span>JSX fragments</span>

135

are experimentally supported

136

</>

137

);

138

```

139

140

## Function Components

141

142

Create reusable function components that receive props and return virtual nodes.

143

144

```typescript { .api }

145

type FunctionComponent = (

146

props: { [prop: string]: any } | null,

147

children?: VNode[]

148

) => VNode;

149

```

150

151

**Usage Examples:**

152

153

```typescript

154

import { jsx, VNode, h } from "snabbdom";

155

156

// Simple function component

157

function Greeting(props: { name: string } | null): VNode {

158

return <h1>Hello, {props?.name || "World"}!</h1>;

159

}

160

161

// Function component with children

162

function Card(

163

props: { title: string; className?: string } | null,

164

children?: VNode[]

165

): VNode {

166

return (

167

<div class={props?.className || "card"}>

168

<h2>{props?.title}</h2>

169

<div class="card-body">

170

{children}

171

</div>

172

</div>

173

);

174

}

175

176

// Using function components

177

const app: VNode = (

178

<div>

179

<Greeting name="Snabbdom" />

180

<Card title="Welcome" className="welcome-card">

181

<p>This is card content</p>

182

<button>Action</button>

183

</Card>

184

</div>

185

);

186

```

187

188

## Conditional Rendering

189

190

JSX supports conditional rendering with boolean expressions.

191

192

```typescript

193

import { jsx, VNode } from "snabbdom";

194

195

function ConditionalExample(props: { showMessage: boolean } | null): VNode {

196

return (

197

<div>

198

<h1>Conditional Rendering</h1>

199

{props?.showMessage && <p>This message is conditionally shown</p>}

200

{props?.showMessage ? <p>Condition is true</p> : <p>Condition is false</p>}

201

</div>

202

);

203

}

204

```

205

206

## Working with Lists

207

208

Map over arrays to create lists of elements.

209

210

```typescript

211

import { jsx, VNode } from "snabbdom";

212

213

interface User {

214

id: number;

215

name: string;

216

email: string;

217

}

218

219

function UserList(props: { users: User[] } | null): VNode {

220

const users = props?.users || [];

221

222

return (

223

<ul class="user-list">

224

{users.map(user => (

225

<li key={user.id} class="user-item">

226

<strong>{user.name}</strong> - {user.email}

227

</li>

228

))}

229

</ul>

230

);

231

}

232

233

// Usage

234

const users: User[] = [

235

{ id: 1, name: "Alice", email: "alice@example.com" },

236

{ id: 2, name: "Bob", email: "bob@example.com" }

237

];

238

239

const userListVNode = <UserList users={users} />;

240

```

241

242

## Types

243

244

```typescript { .api }

245

type JsxVNodeChild = VNode | string | number | boolean | undefined | null;

246

type JsxVNodeChildren = ArrayOrElement<JsxVNodeChild>;

247

248

type ArrayOrElement<T> = T | T[];

249

250

namespace jsx {

251

type Element = VNode;

252

253

type VNodeProps<T> = ElementProperties<T> & Props;

254

255

type HtmlElements = {

256

[Property in keyof HTMLElementTagNameMap]: VNodeData<

257

VNodeProps<HTMLElementTagNameMap[Property]>

258

>;

259

};

260

261

interface IntrinsicElements extends HtmlElements {

262

[elemName: string]: VNodeData;

263

}

264

}

265

```