or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md
tile.json

index.mddocs/

0

# @lit/react

1

2

@lit/react provides React integration for Web Components and Reactive Controllers, enabling seamless interoperability between React applications and web components. The library offers utilities for property binding, event handling, and controller composition while maintaining type safety and following React patterns.

3

4

## Package Information

5

6

- **Package Name**: @lit/react

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @lit/react`

10

11

## Core Imports

12

13

```typescript

14

import { createComponent } from "@lit/react";

15

import type { EventName, ReactWebComponent, WebComponentProps } from "@lit/react";

16

```

17

18

For the controller hook:

19

20

```typescript

21

import { useController } from "@lit/react/use-controller.js";

22

import type { ControllerConstructor } from "@lit/react/use-controller.js";

23

```

24

25

## Basic Usage

26

27

### Creating React Component Wrappers

28

29

```typescript

30

import * as React from 'react';

31

import { createComponent } from '@lit/react';

32

import { MyElement } from './my-element.js';

33

34

export const MyElementComponent = createComponent({

35

tagName: 'my-element',

36

elementClass: MyElement,

37

react: React,

38

events: {

39

onactivate: 'activate',

40

onchange: 'change',

41

},

42

});

43

44

// Usage in JSX

45

<MyElementComponent

46

active={isActive}

47

onactivate={(e) => setIsActive(e.active)}

48

/>

49

```

50

51

### Using Reactive Controllers

52

53

```typescript

54

import * as React from 'react';

55

import { useController } from '@lit/react/use-controller.js';

56

import { MouseController } from '@example/mouse-controller';

57

58

const useMouse = () => {

59

const controller = useController(React, (host) => new MouseController(host));

60

return controller.position;

61

};

62

63

const Component = () => {

64

const mousePosition = useMouse();

65

return <pre>x: {mousePosition.x} y: {mousePosition.y}</pre>;

66

};

67

```

68

69

## Architecture

70

71

@lit/react is built around two main integration patterns:

72

73

- **Component Wrapper Pattern**: `createComponent()` creates React components that properly bridge React props and web component properties/events

74

- **Controller Hook Pattern**: `useController()` adapts Lit's Reactive Controller lifecycle to React's hook system

75

- **Type Safety**: Full TypeScript integration with generic types for custom elements and events

76

- **Lifecycle Integration**: Proper integration with React's render lifecycle using `useLayoutEffect`

77

- **Server-Side Rendering**: Built-in support for SSR scenarios with `@lit/ssr-react`

78

79

## Capabilities

80

81

### Web Component Integration

82

83

Creates React component wrappers for custom elements with proper property binding and event handling, addressing React's default limitations with web components.

84

85

```typescript { .api }

86

/**

87

* Creates a React component for a custom element with proper property binding and event handling

88

* @param options Configuration object for the component wrapper

89

* @returns React ForwardRefExoticComponent that wraps the custom element

90

*/

91

function createComponent<I extends HTMLElement, E extends EventNames = {}>(

92

options: Options<I, E>

93

): ReactWebComponent<I, E>;

94

95

interface Options<I extends HTMLElement, E extends EventNames = {}> {

96

/** The React module, typically imported from the 'react' npm package */

97

react: typeof React;

98

/** The custom element tag name registered via customElements.define */

99

tagName: string;

100

/** The custom element class registered via customElements.define */

101

elementClass: Constructor<I>;

102

/** Object mapping React event prop names to custom element event names */

103

events?: E;

104

/** React component display name for debugging (defaults to element class name) */

105

displayName?: string;

106

}

107

108

type Constructor<T> = { new (): T };

109

type EventNames = Record<string, EventName | string>;

110

```

111

112

### Reactive Controller Integration

113

114

React hook that creates and manages Reactive Controllers using React's lifecycle, enabling controller composition and state management patterns from Lit in React components.

115

116

```typescript { .api }

117

/**

118

* Creates and stores a stateful ReactiveController instance with React lifecycle integration

119

* @param React The React module providing useState and useLayoutEffect hooks

120

* @param createController Function that creates a controller instance given a host

121

* @returns The created controller instance

122

*/

123

function useController<C extends ReactiveController>(

124

React: typeof window.React,

125

createController: (host: ReactiveControllerHost) => C

126

): C;

127

128

// ReactiveController and ReactiveControllerHost are imported from @lit/reactive-element

129

interface ReactiveController {

130

hostConnected?(): void;

131

hostDisconnected?(): void;

132

hostUpdate?(): void;

133

hostUpdated?(): void;

134

}

135

136

interface ReactiveControllerHost {

137

addController(controller: ReactiveController): void;

138

removeController(controller: ReactiveController): void;

139

requestUpdate(): void;

140

readonly updateComplete: Promise<boolean>;

141

}

142

143

type ControllerConstructor<C extends ReactiveController> = {

144

new (...args: Array<any>): C;

145

};

146

```

147

148

### Type System

149

150

Type utilities for enhanced TypeScript integration and type-safe event handling.

151

152

```typescript { .api }

153

/**

154

* Props type for web component used directly in React JSX

155

*/

156

type WebComponentProps<I extends HTMLElement> = React.DetailedHTMLProps<

157

React.HTMLAttributes<I>,

158

I

159

> & ElementProps<I>;

160

161

/**

162

* Type of the React component wrapping the web component (return type of createComponent)

163

*/

164

type ReactWebComponent<I extends HTMLElement, E extends EventNames = {}> =

165

React.ForwardRefExoticComponent<

166

ComponentProps<I, E> & React.RefAttributes<I>

167

>;

168

169

// Helper types used in the API

170

type ElementProps<I> = Partial<Omit<I, keyof HTMLElement>>;

171

172

type ComponentProps<I, E extends EventNames = {}> = Omit<

173

React.HTMLAttributes<I>,

174

keyof E | keyof ElementProps<I>

175

> & EventListeners<E> & ElementProps<I>;

176

177

type EventListeners<R extends EventNames> = {

178

[K in keyof R]?: R[K] extends EventName

179

? (e: R[K]['__eventType']) => void

180

: (e: Event) => void;

181

};

182

183

/**

184

* Type for casting event names with event types for better typing of event handler props

185

* @example

186

* events: {

187

* onfoo: 'foo' as EventName<FooEvent>,

188

* }

189

*/

190

type EventName<T extends Event = Event> = string & {

191

__eventType: T;

192

};

193

```

194

195

## Controller Host Implementation

196

197

The library includes a React-driven implementation of ReactiveControllerHost that bridges Lit's controller lifecycle with React hooks through an internal `ReactControllerHost` class that manages the controller lifecycle using React's `useState` and `useLayoutEffect` hooks.

198

199

## Event Handling

200

201

Enhanced event handling with type safety for custom element events.

202

203

**Basic Event Mapping:**

204

205

```typescript

206

const Component = createComponent({

207

tagName: 'my-element',

208

elementClass: MyElement,

209

react: React,

210

events: {

211

onchange: 'change',

212

oncustom: 'custom-event',

213

},

214

});

215

```

216

217

**Type-Safe Event Handling:**

218

219

```typescript

220

import type { EventName } from '@lit/react';

221

222

const Component = createComponent({

223

tagName: 'my-element',

224

elementClass: MyElement,

225

react: React,

226

events: {

227

onClick: 'pointerdown' as EventName<PointerEvent>,

228

onChange: 'input',

229

},

230

});

231

232

// Usage with properly typed event handlers

233

<Component

234

onClick={(e: PointerEvent) => console.log('Pointer event:', e)}

235

onChange={(e: Event) => console.log('Input event:', e)}

236

/>

237

```

238

239

## Server-Side Rendering

240

241

The library includes built-in support for server-side rendering when used with `@lit/ssr-react`:

242

243

```typescript

244

// SSR support is automatically enabled when litSsrReactEnabled is true

245

// or when React.createElement.name === 'litPatchedCreateElement'

246

```

247

248

## Error Handling

249

250

The library provides development-time warnings for potential integration issues:

251

252

- Warns when custom elements define properties that conflict with React reserved properties

253

- Handles property/attribute synchronization edge cases

254

- Provides proper cleanup for event listeners and controller lifecycle