or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-context.mdfield-templates.mdfields.mdform-components.mdindex.mdthemes.mdwidgets.md

component-context.mddocs/

0

# Component Context

1

2

React Context system for providing Material UI components to form elements, enabling version compatibility and dependency injection. The context system allows widgets and fields to access Material UI components without direct imports.

3

4

## Capabilities

5

6

### MuiComponentContext

7

8

React Context that provides Material UI components to all child widgets and fields.

9

10

```typescript { .api }

11

/**

12

* React Context for providing Material UI components to widgets and fields

13

* Can hold either Material UI v4 or v5 component references

14

*/

15

declare const MuiComponentContext: React.Context<MaterialUIContextProps | Mui5ContextProps | null>;

16

```

17

18

**Features:**

19

- Version-agnostic component access

20

- Dependency injection for Material UI components

21

- Null-safe context handling

22

- Support for both v4 and v5 simultaneously

23

24

**Usage:**

25

- Automatically provided by form wrappers

26

- Accessed via useMuiComponent hook

27

- Can be customized for testing or specialized use cases

28

29

### useMuiComponent Hook

30

31

Hook for accessing Material UI components from the context within widgets and fields.

32

33

```typescript { .api }

34

/**

35

* Hook to access Material UI components from context

36

* @returns MaterialUIContextProps | Mui5ContextProps

37

* @throws Error if no context provider is found

38

*/

39

function useMuiComponent(): MaterialUIContextProps | Mui5ContextProps;

40

```

41

42

**Features:**

43

- Type-safe component access

44

- Runtime error checking

45

- Version detection

46

- Component availability validation

47

48

**Usage:**

49

```typescript

50

import { useMuiComponent } from "@rjsf/material-ui";

51

52

function CustomWidget(props: WidgetProps) {

53

const { TextField, Button } = useMuiComponent();

54

55

return (

56

<TextField

57

value={props.value}

58

onChange={(e) => props.onChange(e.target.value)}

59

/>

60

);

61

}

62

```

63

64

## Context Types

65

66

### MaterialUIContextProps (v4)

67

68

Interface defining Material UI v4 component structure:

69

70

```typescript { .api }

71

interface MaterialUIContextProps {

72

Box: React.ComponentType<BoxProps>;

73

Button: React.ComponentType<ButtonProps>;

74

Checkbox: React.ComponentType<CheckboxProps>;

75

Divider: React.ComponentType<DividerProps>;

76

Grid: React.ComponentType<GridProps>;

77

FormControl: React.ComponentType<FormControlProps>;

78

FormControlLabel: React.ComponentType<FormControlLabelProps>;

79

FormGroup: React.ComponentType<FormGroupProps>;

80

FormHelperText: React.ComponentType<FormHelperTextProps>;

81

FormLabel: React.ComponentType<FormLabelProps>;

82

IconButton: React.ComponentType<IconButtonProps>;

83

Input: React.ComponentType<InputProps>;

84

InputLabel: React.ComponentType<InputLabelProps>;

85

List: React.ComponentType<ListProps>;

86

ListItem: React.ComponentType<ListItemProps>;

87

ListItemIcon: React.ComponentType<ListItemIconProps>;

88

ListItemText: React.ComponentType<ListItemTextProps>;

89

MenuItem: React.ComponentType<MenuItemProps>;

90

Paper: React.ComponentType<PaperProps>;

91

Radio: React.ComponentType<RadioProps>;

92

RadioGroup: React.ComponentType<RadioGroupProps>;

93

Slider: React.ComponentType<SliderProps>;

94

TextField: React.ComponentType<Omit<TextFieldProps, 'color' | 'variant'>>;

95

Typography: React.ComponentType<TypographyProps>;

96

AddIcon: React.ComponentType<SvgIconProps>;

97

ArrowDownwardIcon: React.ComponentType<SvgIconProps>;

98

ArrowUpwardIcon: React.ComponentType<SvgIconProps>;

99

ErrorIcon: React.ComponentType<SvgIconProps>;

100

RemoveIcon: React.ComponentType<SvgIconProps>;

101

}

102

```

103

104

### Mui5ContextProps (v5)

105

106

Interface defining Material UI v5 component structure:

107

108

```typescript { .api }

109

interface Mui5ContextProps {

110

Box: React.ComponentType<BoxProps>;

111

Button: React.ComponentType<ButtonProps>;

112

Checkbox: React.ComponentType<CheckboxProps>;

113

Divider: React.ComponentType<DividerProps>;

114

Grid: React.ComponentType<GridProps>;

115

FormControl: React.ComponentType<FormControlProps>;

116

FormControlLabel: React.ComponentType<FormControlLabelProps>;

117

FormGroup: React.ComponentType<FormGroupProps>;

118

FormHelperText: React.ComponentType<FormHelperTextProps>;

119

FormLabel: React.ComponentType<FormLabelProps>;

120

IconButton: React.ComponentType<IconButtonProps>;

121

Input: React.ComponentType<OutlinedInputProps>; // Different from v4

122

InputLabel: React.ComponentType<InputLabelProps>;

123

List: React.ComponentType<ListProps>;

124

ListItem: React.ComponentType<ListItemProps>;

125

ListItemIcon: React.ComponentType<ListItemIconProps>;

126

ListItemText: React.ComponentType<ListItemTextProps>;

127

MenuItem: React.ComponentType<MenuItemProps>;

128

Paper: React.ComponentType<PaperProps>;

129

Radio: React.ComponentType<RadioProps>;

130

RadioGroup: React.ComponentType<RadioGroupProps>;

131

Slider: React.ComponentType<SliderProps>;

132

TextField: React.ComponentType<Omit<TextFieldProps, 'color' | 'variant'>>;

133

Typography: React.ComponentType<TypographyProps>;

134

AddIcon: React.ComponentType<SvgIconProps>;

135

ArrowDownwardIcon: React.ComponentType<SvgIconProps>;

136

ArrowUpwardIcon: React.ComponentType<SvgIconProps>;

137

ErrorIcon: React.ComponentType<SvgIconProps>;

138

RemoveIcon: React.ComponentType<SvgIconProps>;

139

}

140

```

141

142

## Context Providers

143

144

### MaterialUIContext (v4)

145

146

Context value object containing Material UI v4 component references:

147

148

```typescript { .api }

149

/**

150

* Object containing @material-ui/core v4 component references

151

* Null if Material UI v4 dependencies are not available

152

*/

153

declare const MaterialUIContext: MaterialUIContextProps | null;

154

```

155

156

### Mui5Context (v5)

157

158

Context value object containing Material UI v5 component references:

159

160

```typescript { .api }

161

/**

162

* Object containing @mui/material v5 component references

163

* Null if Material UI v5 dependencies are not available

164

*/

165

declare const Mui5Context: Mui5ContextProps | null;

166

```

167

168

## Usage Examples

169

170

### Custom Widget with Context

171

172

```typescript

173

import { useMuiComponent } from "@rjsf/material-ui";

174

import { WidgetProps } from "@rjsf/core";

175

176

const CustomTextWidget: React.FC<WidgetProps> = (props) => {

177

const { TextField, FormControl, FormHelperText } = useMuiComponent();

178

179

return (

180

<FormControl fullWidth>

181

<TextField

182

id={props.id}

183

label={props.label}

184

value={props.value || ""}

185

onChange={(event) => props.onChange(event.target.value)}

186

onBlur={() => props.onBlur && props.onBlur(props.id, props.value)}

187

onFocus={() => props.onFocus && props.onFocus(props.id, props.value)}

188

disabled={props.disabled}

189

readonly={props.readonly}

190

required={props.required}

191

error={props.rawErrors && props.rawErrors.length > 0}

192

/>

193

{props.rawErrors && props.rawErrors.length > 0 && (

194

<FormHelperText error>

195

{props.rawErrors.join(", ")}

196

</FormHelperText>

197

)}

198

</FormControl>

199

);

200

};

201

```

202

203

### Context-Aware Component

204

205

```typescript

206

import { useMuiComponent } from "@rjsf/material-ui";

207

208

const VersionAwareComponent: React.FC = () => {

209

const components = useMuiComponent();

210

211

// Detect version by checking component differences

212

const isV5 = 'Input' in components &&

213

components.Input.toString().includes('OutlinedInput');

214

215

return (

216

<div>

217

<p>Using Material UI {isV5 ? 'v5' : 'v4'}</p>

218

<components.Button variant="contained">

219

Click me

220

</components.Button>

221

</div>

222

);

223

};

224

```

225

226

### Custom Context Provider

227

228

```typescript

229

import { MuiComponentContext } from "@rjsf/material-ui";

230

import * as MuiV5 from "@mui/material";

231

import * as MuiIcons from "@mui/icons-material";

232

233

const customContextValue: Mui5ContextProps = {

234

...MuiV5,

235

AddIcon: MuiIcons.Add,

236

ArrowDownwardIcon: MuiIcons.ArrowDownward,

237

ArrowUpwardIcon: MuiIcons.ArrowUpward,

238

ErrorIcon: MuiIcons.Error,

239

RemoveIcon: MuiIcons.Remove,

240

};

241

242

function CustomContextProvider({ children }: { children: React.ReactNode }) {

243

return (

244

<MuiComponentContext.Provider value={customContextValue}>

245

{children}

246

</MuiComponentContext.Provider>

247

);

248

}

249

```

250

251

### Error Handling

252

253

```typescript

254

import { useMuiComponent } from "@rjsf/material-ui";

255

256

const SafeWidget: React.FC<WidgetProps> = (props) => {

257

try {

258

const { TextField } = useMuiComponent();

259

260

return (

261

<TextField

262

value={props.value}

263

onChange={(e) => props.onChange(e.target.value)}

264

/>

265

);

266

} catch (error) {

267

return (

268

<div style={{ color: 'red' }}>

269

Material UI components not available: {error.message}

270

</div>

271

);

272

}

273

};

274

```

275

276

### Testing with Mock Context

277

278

```typescript

279

import { render } from "@testing-library/react";

280

import { MuiComponentContext } from "@rjsf/material-ui";

281

282

const mockContext: Partial<MaterialUIContextProps> = {

283

TextField: ({ value, onChange }) => (

284

<input value={value} onChange={(e) => onChange(e)} />

285

),

286

Button: ({ children, onClick }) => (

287

<button onClick={onClick}>{children}</button>

288

),

289

};

290

291

function renderWithMockContext(component: React.ReactElement) {

292

return render(

293

<MuiComponentContext.Provider value={mockContext as any}>

294

{component}

295

</MuiComponentContext.Provider>

296

);

297

}

298

299

// Usage in tests

300

test("widget renders correctly", () => {

301

const { getByRole } = renderWithMockContext(<CustomWidget {...props} />);

302

expect(getByRole("textbox")).toBeInTheDocument();

303

});

304

```

305

306

## Context Architecture

307

308

The context system provides several key benefits:

309

310

1. **Version Abstraction**: Widgets don't need to know which Material UI version is being used

311

2. **Dependency Injection**: Components are provided rather than imported directly

312

3. **Testing Support**: Easy to mock components for unit testing

313

4. **Bundle Optimization**: Only the required Material UI version is included in the bundle

314

5. **Runtime Detection**: Graceful handling when dependencies are missing

315

316

## Error States

317

318

The context system handles several error conditions:

319

320

- **Missing Dependencies**: Shows warning when Material UI packages aren't installed

321

- **Version Conflicts**: Detects and handles mixed v4/v5 installations

322

- **Context Unavailable**: Throws descriptive error when useMuiComponent is called outside provider

323

- **Component Missing**: Graceful degradation when specific components aren't available

324

325

The form wrappers automatically display user-friendly warnings when Material UI dependencies are not available, preventing runtime crashes and providing clear guidance for resolution.