or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-configuration.mdcomponent-interface.mdcomponent-overrides.mdcore-compilation.mdcustom-rendering.mdindex.mdutility-functions.md

component-overrides.mddocs/

0

# Component Overrides

1

2

Powerful system for replacing any HTML tag with custom React components, including props injection and component mapping.

3

4

## Capabilities

5

6

### Override System

7

8

Flexible mechanism to replace any HTML tag rendered by markdown with custom React components or modified props.

9

10

```typescript { .api }

11

interface Override {

12

/** React component to replace the default HTML tag */

13

component?: React.ElementType;

14

/** Props to inject into the rendered element */

15

props?: object;

16

}

17

18

type Overrides = {

19

/** Override any standard HTML tag */

20

[tag in HTMLTags]?: Override | React.ElementType;

21

} & {

22

/** Override custom components by name */

23

[customComponent: string]: Override | React.ElementType;

24

};

25

26

type HTMLTags = keyof React.JSX.IntrinsicElements;

27

```

28

29

**Usage Examples:**

30

31

```typescript

32

import Markdown from "markdown-to-jsx";

33

import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";

34

35

// Component replacement

36

const CustomLink = ({ href, children, ...props }) => (

37

<a

38

href={href}

39

target="_blank"

40

rel="noopener noreferrer"

41

className="external-link"

42

{...props}

43

>

44

{children} πŸ”—

45

</a>

46

);

47

48

// Props injection

49

const markdownOptions = {

50

overrides: {

51

// Replace component entirely

52

a: CustomLink,

53

54

// Component with props

55

h1: {

56

component: "h2",

57

props: { className: "main-title" }

58

},

59

60

// Props only (keeps original tag)

61

p: {

62

props: { className: "paragraph" }

63

},

64

65

// Code block with syntax highlighting

66

code: {

67

component: ({ className, children, ...props }) => {

68

const lang = className?.replace('lang-', '') || 'text';

69

return (

70

<SyntaxHighlighter language={lang} {...props}>

71

{children}

72

</SyntaxHighlighter>

73

);

74

}

75

}

76

}

77

};

78

79

function App() {

80

return (

81

<Markdown options={markdownOptions}>

82

# This becomes h2 with class "main-title"

83

84

This paragraph gets the "paragraph" class.

85

86

[This link](https://example.com) opens in new tab with icon.

87

88

```javascript

89

// This code gets syntax highlighting

90

const hello = "world";

91

```

92

</Markdown>

93

);

94

}

95

```

96

97

### Component Replacement

98

99

Replace any HTML tag with a custom React component while preserving all functionality.

100

101

```typescript { .api }

102

/**

103

* Replace HTML tag with custom component

104

* Component receives all standard HTML attributes plus children

105

*/

106

type ComponentOverride = React.ElementType;

107

108

// Usage in overrides

109

const overrides = {

110

tagName: CustomComponent

111

};

112

```

113

114

**Usage Examples:**

115

116

```typescript

117

// Custom heading component

118

const CustomHeading = ({ level, id, children, ...props }) => {

119

const Tag = `h${level}`;

120

return (

121

<Tag

122

id={id}

123

className={`heading-${level}`}

124

{...props}

125

>

126

<span className="heading-icon">#</span>

127

{children}

128

</Tag>

129

);

130

};

131

132

// Custom image component with lazy loading

133

const LazyImage = ({ src, alt, title, ...props }) => {

134

return (

135

<img

136

src={src}

137

alt={alt}

138

title={title}

139

loading="lazy"

140

className="responsive-image"

141

{...props}

142

/>

143

);

144

};

145

146

// Custom list component

147

const CustomList = ({ ordered, start, children, ...props }) => {

148

const Tag = ordered ? "ol" : "ul";

149

return (

150

<Tag

151

start={start}

152

className={`list ${ordered ? 'ordered' : 'unordered'}`}

153

{...props}

154

>

155

{children}

156

</Tag>

157

);

158

};

159

160

const options = {

161

overrides: {

162

h1: CustomHeading,

163

h2: CustomHeading,

164

h3: CustomHeading,

165

img: LazyImage,

166

ul: CustomList,

167

ol: CustomList

168

}

169

};

170

```

171

172

### Props Injection

173

174

Add or modify props for HTML elements without changing the component type.

175

176

```typescript { .api }

177

/**

178

* Props injection configuration

179

* Props are merged with existing attributes, with override props taking precedence

180

*/

181

interface PropsOverride {

182

props: object;

183

component?: React.ElementType; // Optional component replacement

184

}

185

```

186

187

**Usage Examples:**

188

189

```typescript

190

const options = {

191

overrides: {

192

// Add classes to all paragraphs

193

p: {

194

props: { className: "prose-paragraph" }

195

},

196

197

// Style all blockquotes

198

blockquote: {

199

props: {

200

className: "quote",

201

style: {

202

borderLeft: "4px solid #ccc",

203

paddingLeft: "1rem",

204

fontStyle: "italic"

205

}

206

}

207

},

208

209

// Make all tables responsive

210

table: {

211

props: {

212

className: "table-responsive",

213

style: { width: "100%" }

214

}

215

},

216

217

// Add target to all links

218

a: {

219

props: {

220

target: "_blank",

221

rel: "noopener noreferrer"

222

}

223

}

224

}

225

};

226

227

// Markdown content

228

const content = `

229

# Title

230

231

This is a paragraph that will get the "prose-paragraph" class.

232

233

> This blockquote gets custom styling.

234

235

| Col 1 | Col 2 |

236

|-------|-------|

237

| A | B |

238

239

[This link](https://example.com) opens in new tab.

240

`;

241

```

242

243

### Class Name Merging

244

245

Override props are intelligently merged with existing attributes, with special handling for className.

246

247

```typescript

248

// Built-in classes are preserved and merged

249

const options = {

250

overrides: {

251

code: {

252

props: { className: "custom-code" }

253

}

254

}

255

};

256

257

// Fenced code block with language

258

const markdown = `

259

\`\`\`javascript

260

const code = "example";

261

\`\`\`

262

`;

263

264

// Results in: <code className="lang-javascript custom-code">

265

```

266

267

### Advanced Override Patterns

268

269

Complex override scenarios for sophisticated component replacement and prop manipulation.

270

271

**Usage Examples:**

272

273

```typescript

274

// Conditional component based on props

275

const SmartImage = ({ alt, src, ...props }) => {

276

const isExternal = src.startsWith('http');

277

278

if (isExternal) {

279

return (

280

<figure className="external-image">

281

<img src={src} alt={alt} {...props} />

282

<figcaption>External: {alt}</figcaption>

283

</figure>

284

);

285

}

286

287

return <img src={src} alt={alt} {...props} />;

288

};

289

290

// Dynamic component based on content

291

const SmartCode = ({ className, children, ...props }) => {

292

const language = className?.replace('lang-', '');

293

294

// Inline code

295

if (!language) {

296

return <code className="inline-code" {...props}>{children}</code>;

297

}

298

299

// Block code with syntax highlighting

300

return (

301

<SyntaxHighlighter

302

language={language}

303

className="code-block"

304

{...props}

305

>

306

{children}

307

</SyntaxHighlighter>

308

);

309

};

310

311

// Wrapper component that adds functionality

312

const InteractiveHeading = ({ children, id, ...props }) => {

313

const handleClick = () => {

314

navigator.clipboard.writeText(`#${id}`);

315

};

316

317

return (

318

<h2 id={id} onClick={handleClick} className="interactive-heading" {...props}>

319

{children}

320

<button className="copy-link" aria-label="Copy link">πŸ”—</button>

321

</h2>

322

);

323

};

324

325

const advancedOptions = {

326

overrides: {

327

img: SmartImage,

328

code: SmartCode,

329

h2: InteractiveHeading

330

}

331

};

332

```

333

334

### Override Validation

335

336

TypeScript provides compile-time validation for override configurations to prevent common mistakes.

337

338

```typescript

339

const options = {

340

overrides: {

341

// βœ… Valid - React component

342

p: CustomParagraph,

343

344

// βœ… Valid - HTML tag string

345

h1: "h2",

346

347

// βœ… Valid - Override object

348

a: {

349

component: CustomLink,

350

props: { className: "link" }

351

},

352

353

// ❌ TypeScript error - invalid override

354

span: { invalidProp: true },

355

356

// ❌ TypeScript error - not a valid HTML tag

357

invalidTag: CustomComponent

358

}

359

};

360

```