or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdcomponent-extension.mdhooks.mdindex.mdjsx-elements.mdroot-creation.md

jsx-elements.mddocs/

0

# JSX Elements

1

2

@pixi/react provides type-safe JSX elements for all PixiJS components through a sophisticated type system. Components must be registered with `extend()` before use, supporting both prefixed and unprefixed usage patterns.

3

4

## Capabilities

5

6

### PixiJS Component Elements

7

8

All extended PixiJS components are available as JSX elements with automatic type safety and event handling.

9

10

```typescript { .api }

11

/**

12

* Type-safe JSX elements for PixiJS components

13

* Components must be registered via extend() before use

14

*/

15

interface PixiElements extends PrefixedPixiElements {}

16

17

type PrefixedPixiElements = {

18

[K in keyof UnprefixedPixiElements as `pixi${Capitalize<string & K>}`]: UnprefixedPixiElements[K];

19

};

20

21

type UnprefixedPixiElements = {

22

[K in PixiComponents as K extends keyof NameOverrides ? NameOverrides[K] : Uncapitalize<K>]:

23

PixiReactElementProps<typeof PIXI[K]>;

24

};

25

26

type PixiReactElementProps<T extends new (...args: any) => any> =

27

BaseNodeProps<InstanceType<T>>

28

& GraphicsProps<InstanceType<T>>

29

& EventHandlers

30

& ConstructorOptions<T>;

31

```

32

33

**Usage Examples:**

34

35

```typescript

36

import { extend } from "@pixi/react";

37

import { Container, Graphics, Text, Sprite } from "pixi.js";

38

39

extend({ Container, Graphics, Text, Sprite });

40

41

// Basic element usage

42

const BasicElements = () => (

43

<pixiContainer x={100} y={100} alpha={0.8}>

44

<pixiText

45

text="Hello World!"

46

x={50}

47

y={50}

48

style={{ fontSize: 24, fill: "white" }}

49

/>

50

<pixiSprite

51

texture={myTexture}

52

anchor={0.5}

53

interactive

54

onPointerDown={(event) => console.log("Clicked!", event)}

55

/>

56

</pixiContainer>

57

);

58

59

// All PixiJS properties are supported

60

const AdvancedElements = () => (

61

<pixiContainer

62

x={200}

63

y={150}

64

rotation={Math.PI / 4}

65

scale={{ x: 1.5, y: 1.5 }}

66

pivot={{ x: 50, y: 50 }}

67

alpha={0.9}

68

visible={true}

69

interactive={true}

70

interactiveChildren={true}

71

hitArea={new Rectangle(0, 0, 100, 100)}

72

mask={maskGraphics}

73

filters={[blurFilter]}

74

zIndex={10}

75

>

76

<pixiGraphics

77

draw={(graphics) => {

78

graphics.clear();

79

graphics.setFillStyle({ color: "red" });

80

graphics.rect(0, 0, 100, 100);

81

graphics.fill();

82

}}

83

interactive

84

onPointerMove={(event) => {

85

console.log("Mouse position:", event.global.x, event.global.y);

86

}}

87

/>

88

</pixiContainer>

89

);

90

```

91

92

### Graphics Elements

93

94

Graphics components have special support for the `draw` callback function.

95

96

```typescript { .api }

97

/**

98

* Graphics elements support special draw callback for rendering

99

*/

100

type GraphicsProps<T> = T extends Graphics ? { draw: DrawCallback } : unknown;

101

102

type DrawCallback = (graphics: Graphics) => void;

103

```

104

105

**Usage Examples:**

106

107

```typescript

108

import { extend } from "@pixi/react";

109

import { Graphics } from "pixi.js";

110

import { useCallback, useState } from "react";

111

112

extend({ Graphics });

113

114

// Simple graphics drawing

115

const SimpleGraphics = () => {

116

const drawRect = useCallback((graphics: Graphics) => {

117

graphics.clear();

118

graphics.setFillStyle({ color: "blue" });

119

graphics.rect(0, 0, 100, 100);

120

graphics.fill();

121

}, []);

122

123

return <pixiGraphics draw={drawRect} x={100} y={100} />;

124

};

125

126

// Dynamic graphics with state

127

const DynamicGraphics = () => {

128

const [color, setColor] = useState("red");

129

130

const drawCircle = useCallback((graphics: Graphics) => {

131

graphics.clear();

132

graphics.setFillStyle({ color });

133

graphics.circle(0, 0, 50);

134

graphics.fill();

135

graphics.setStrokeStyle({ color: "white", width: 2 });

136

graphics.stroke();

137

}, [color]);

138

139

return (

140

<pixiContainer>

141

<pixiGraphics

142

draw={drawCircle}

143

x={200}

144

y={200}

145

interactive

146

onPointerTap={() => {

147

const colors = ["red", "green", "blue", "yellow"];

148

const nextColor = colors[Math.floor(Math.random() * colors.length)];

149

setColor(nextColor);

150

}}

151

/>

152

</pixiContainer>

153

);

154

};

155

156

// Complex graphics shapes

157

const ComplexGraphics = () => {

158

const drawShape = useCallback((graphics: Graphics) => {

159

graphics.clear();

160

161

// Draw a star shape

162

graphics.setFillStyle({

163

color: "gold",

164

alpha: 0.8

165

});

166

167

const outerRadius = 60;

168

const innerRadius = 30;

169

const points = 5;

170

171

graphics.moveTo(outerRadius, 0);

172

173

for (let i = 1; i <= points * 2; i++) {

174

const radius = i % 2 === 0 ? outerRadius : innerRadius;

175

const angle = (i * Math.PI) / points;

176

graphics.lineTo(

177

Math.cos(angle) * radius,

178

Math.sin(angle) * radius

179

);

180

}

181

182

graphics.closePath();

183

graphics.fill();

184

185

// Add stroke

186

graphics.setStrokeStyle({ color: "orange", width: 3 });

187

graphics.stroke();

188

}, []);

189

190

return <pixiGraphics draw={drawShape} x={300} y={300} />;

191

};

192

```

193

194

### Event Handling

195

196

All PixiJS events are supported with automatic type conversion from React event props.

197

198

```typescript { .api }

199

/**

200

* Event handlers for PixiJS interaction events

201

* React event prop names are automatically converted to PixiJS event names

202

*/

203

interface EventHandlers {

204

// Pointer events

205

onPointerDown?: (event: FederatedPointerEvent) => void;

206

onPointerUp?: (event: FederatedPointerEvent) => void;

207

onPointerMove?: (event: FederatedPointerEvent) => void;

208

onPointerTap?: (event: FederatedPointerEvent) => void;

209

onPointerOver?: (event: FederatedPointerEvent) => void;

210

onPointerOut?: (event: FederatedPointerEvent) => void;

211

onPointerEnter?: (event: FederatedPointerEvent) => void;

212

onPointerLeave?: (event: FederatedPointerEvent) => void;

213

214

// Mouse events

215

onMouseDown?: (event: FederatedMouseEvent) => void;

216

onMouseUp?: (event: FederatedMouseEvent) => void;

217

onMouseMove?: (event: FederatedMouseEvent) => void;

218

onMouseOver?: (event: FederatedMouseEvent) => void;

219

onMouseOut?: (event: FederatedMouseEvent) => void;

220

221

// Touch events

222

onTouchStart?: (event: FederatedTouchEvent) => void;

223

onTouchEnd?: (event: FederatedTouchEvent) => void;

224

onTouchMove?: (event: FederatedTouchEvent) => void;

225

226

// Wheel events

227

onWheel?: (event: FederatedWheelEvent) => void;

228

}

229

```

230

231

**Usage Examples:**

232

233

```typescript

234

// Interactive sprite with multiple event handlers

235

const InteractiveSprite = ({ texture }) => {

236

const [isHovered, setIsHovered] = useState(false);

237

const [isPressed, setIsPressed] = useState(false);

238

239

return (

240

<pixiSprite

241

texture={texture}

242

interactive

243

alpha={isHovered ? 0.8 : 1}

244

scale={isPressed ? 0.9 : 1}

245

onPointerEnter={() => setIsHovered(true)}

246

onPointerLeave={() => setIsHovered(false)}

247

onPointerDown={() => setIsPressed(true)}

248

onPointerUp={() => setIsPressed(false)}

249

onPointerTap={(event) => {

250

console.log("Tapped at:", event.global.x, event.global.y);

251

}}

252

onRightClick={(event) => {

253

event.preventDefault();

254

console.log("Right clicked!");

255

}}

256

/>

257

);

258

};

259

260

// Draggable container

261

const DraggableContainer = ({ children }) => {

262

const [isDragging, setIsDragging] = useState(false);

263

const [dragStart, setDragStart] = useState({ x: 0, y: 0 });

264

const [position, setPosition] = useState({ x: 0, y: 0 });

265

266

return (

267

<pixiContainer

268

x={position.x}

269

y={position.y}

270

interactive

271

onPointerDown={(event) => {

272

setIsDragging(true);

273

setDragStart({

274

x: event.global.x - position.x,

275

y: event.global.y - position.y,

276

});

277

}}

278

onPointerMove={(event) => {

279

if (isDragging) {

280

setPosition({

281

x: event.global.x - dragStart.x,

282

y: event.global.y - dragStart.y,

283

});

284

}

285

}}

286

onPointerUp={() => setIsDragging(false)}

287

onPointerUpOutside={() => setIsDragging(false)}

288

>

289

{children}

290

</pixiContainer>

291

);

292

};

293

```

294

295

### Component Properties

296

297

All PixiJS component properties are supported with full type safety.

298

299

```typescript { .api }

300

/**

301

* Base properties available on all PixiJS components

302

*/

303

interface BaseNodeProps<T> {

304

/** Child components (Container types only) */

305

children?: T extends Container ? PixiReactChildNode : never;

306

/** React key for list rendering */

307

key?: Key;

308

/** React ref for imperative access */

309

ref?: Ref<T>;

310

}

311

312

/**

313

* Constructor options and properties from PixiJS components

314

* Automatically inferred from the component class

315

*/

316

type ConstructorOptions<T> = ExcludeFunctionProps<T>;

317

```

318

319

**Usage Examples:**

320

321

```typescript

322

// Container with all supported properties

323

const FullContainer = () => (

324

<pixiContainer

325

// Transform properties

326

x={100}

327

y={150}

328

rotation={Math.PI / 6}

329

scale={{ x: 1.2, y: 1.2 }}

330

skew={{ x: 0.1, y: 0 }}

331

pivot={{ x: 50, y: 50 }}

332

anchor={0.5} // If supported by component

333

334

// Display properties

335

alpha={0.8}

336

visible={true}

337

renderable={true}

338

339

// Interaction properties

340

interactive={true}

341

interactiveChildren={true}

342

buttonMode={true}

343

cursor="pointer"

344

345

// Rendering properties

346

mask={maskObject}

347

filters={[blurFilter, colorFilter]}

348

cacheAsBitmap={false}

349

350

// Layout properties

351

zIndex={5}

352

sortableChildren={true}

353

354

// Event properties

355

onPointerDown={(event) => console.log("Clicked")}

356

>

357

{/* Children go here */}

358

</pixiContainer>

359

);

360

361

// Text with typography properties

362

const StyledText = () => (

363

<pixiText

364

text="Styled Text"

365

style={{

366

fontFamily: "Arial",

367

fontSize: 24,

368

fill: "white",

369

stroke: "black",

370

strokeThickness: 2,

371

fontWeight: "bold",

372

textAlign: "center",

373

}}

374

anchor={0.5}

375

x={400}

376

y={300}

377

/>

378

);

379

380

// Sprite with texture properties

381

const ConfiguredSprite = ({ texture }) => (

382

<pixiSprite

383

texture={texture}

384

anchor={{ x: 0.5, y: 1 }}

385

tint="0xff0000"

386

blendMode="multiply"

387

pluginName="batch"

388

roundPixels={true}

389

/>

390

);

391

```

392

393

## Type Safety Features

394

395

The JSX element system provides comprehensive type safety:

396

397

- **Property Validation**: All component properties are type-checked

398

- **Event Type Safety**: Event handlers receive properly typed event objects

399

- **Generic Support**: Components maintain generic type parameters where applicable

400

- **Conditional Properties**: Graphics `draw` prop only available on Graphics components

401

- **Ref Types**: Refs are properly typed to the underlying PixiJS component

402

403

## Component Registration

404

405

Components must be registered before use:

406

407

```typescript

408

import { extend } from "@pixi/react";

409

import { Container, Graphics, Text, Sprite, AnimatedSprite } from "pixi.js";

410

411

// Register before using in JSX

412

extend({

413

Container, // Available as <pixiContainer>

414

Graphics, // Available as <pixiGraphics>

415

Text, // Available as <pixiText>

416

Sprite, // Available as <pixiSprite>

417

AnimatedSprite, // Available as <pixiAnimatedSprite>

418

});

419

```

420

421

Attempting to use unregistered components will result in TypeScript errors and runtime warnings.