npm-react

Description
React is a JavaScript library for building user interfaces with declarative, component-based architecture.
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-react@18.3.0

elements.md docs/

1
# Element Creation & Manipulation
2
3
React elements are the building blocks of React applications. These functions provide ways to create, clone, and validate React elements programmatically, serving as alternatives to JSX syntax.
4
5
## Capabilities
6
7
### createElement
8
9
Creates React elements programmatically - the function that JSX compiles to.
10
11
```javascript { .api }
12
/**
13
* Creates a React element
14
* @param type - Component type, HTML tag name, or React component
15
* @param props - Element props and attributes (null if no props)
16
* @param children - Child elements (variadic arguments)
17
* @returns React element
18
*/
19
function createElement<P extends {}>(
20
type: string | ComponentType<P>,
21
props?: (Attributes & P) | null,
22
...children: ReactNode[]
23
): ReactElement<P>;
24
25
// Overloads for different element types
26
function createElement<P extends HTMLAttributes<T>, T extends HTMLElement>(
27
type: keyof ReactHTML,
28
props?: (ClassAttributes<T> & P) | null,
29
...children: ReactNode[]
30
): DetailedReactHTMLElement<P, T>;
31
32
function createElement<P extends SVGAttributes<T>, T extends SVGElement>(
33
type: keyof ReactSVG,
34
props?: (ClassAttributes<T> & P) | null,
35
...children: ReactNode[]
36
): ReactSVGElement;
37
```
38
39
**Usage Examples:**
40
41
```javascript
42
import React, { createElement } from 'react';
43
44
// Basic HTML elements
45
const heading = createElement('h1', { className: 'title' }, 'Hello World');
46
// Equivalent JSX: <h1 className="title">Hello World</h1>
47
48
const paragraph = createElement('p', null, 'This is a paragraph');
49
// Equivalent JSX: <p>This is a paragraph</p>
50
51
// With multiple children
52
const div = createElement('div', { id: 'container' },
53
createElement('h2', null, 'Section Title'),
54
createElement('p', null, 'Section content'),
55
createElement('button', { onClick: handleClick }, 'Click me')
56
);
57
// Equivalent JSX:
58
// <div id="container">
59
// <h2>Section Title</h2>
60
// <p>Section content</p>
61
// <button onClick={handleClick}>Click me</button>
62
// </div>
63
64
// With React components
65
function MyComponent({ name, age }) {
66
return createElement('div', null,
67
createElement('h3', null, `Name: ${name}`),
68
createElement('p', null, `Age: ${age}`)
69
);
70
}
71
72
const componentElement = createElement(MyComponent, { name: 'John', age: 30 });
73
// Equivalent JSX: <MyComponent name="John" age={30} />
74
75
// Dynamic element creation
76
function createList(items, itemType = 'li') {
77
return createElement('ul', null,
78
...items.map((item, index) =>
79
createElement(itemType, { key: index }, item)
80
)
81
);
82
}
83
84
const todoList = createList(['Buy milk', 'Walk dog', 'Code review']);
85
```
86
87
### cloneElement
88
89
Creates a copy of a React element with new props, preserving the original element's key and ref.
90
91
```javascript { .api }
92
/**
93
* Clones a React element with new props
94
* @param element - React element to clone
95
* @param props - New props to merge (null to keep original props)
96
* @param children - New children (replaces original children)
97
* @returns Cloned React element with merged props
98
*/
99
function cloneElement<P extends {}>(
100
element: ReactElement<P>,
101
props?: (Partial<P> & Attributes) | null,
102
...children: ReactNode[]
103
): ReactElement<P>;
104
```
105
106
**Usage Examples:**
107
108
```javascript
109
import React, { cloneElement, Children } from 'react';
110
111
// Basic cloning with new props
112
function ButtonGroup({ children, variant = 'primary' }) {
113
return (
114
<div className="button-group">
115
{Children.map(children, (child) => {
116
if (React.isValidElement(child)) {
117
return cloneElement(child, {
118
className: `btn btn-${variant}`,
119
size: 'medium'
120
});
121
}
122
return child;
123
})}
124
</div>
125
);
126
}
127
128
// Usage
129
<ButtonGroup variant="secondary">
130
<button onClick={handleSave}>Save</button>
131
<button onClick={handleCancel}>Cancel</button>
132
</ButtonGroup>
133
134
// Enhanced form field wrapper
135
function FormField({ children, error, touched }) {
136
const child = Children.only(children);
137
138
return (
139
<div className={`form-field ${error && touched ? 'error' : ''}`}>
140
{cloneElement(child, {
141
className: `${child.props.className || ''} form-input`,
142
'aria-invalid': error && touched,
143
'aria-describedby': error && touched ? `${child.props.id}-error` : undefined
144
})}
145
{error && touched && (
146
<div id={`${child.props.id}-error`} className="error-message">
147
{error}
148
</div>
149
)}
150
</div>
151
);
152
}
153
154
// Usage
155
<FormField error="Email is required" touched={true}>
156
<input id="email" type="email" placeholder="Enter email" />
157
</FormField>
158
159
// Adding event handlers to existing elements
160
function WithClickTracking({ children, trackingId }) {
161
return Children.map(children, (child) => {
162
if (React.isValidElement(child)) {
163
const originalOnClick = child.props.onClick;
164
165
return cloneElement(child, {
166
onClick: (event) => {
167
// Track click event
168
analytics.track('click', { trackingId, elementType: child.type });
169
170
// Call original handler
171
if (originalOnClick) {
172
originalOnClick(event);
173
}
174
}
175
});
176
}
177
return child;
178
});
179
}
180
181
// Higher-order component using cloneElement
182
function withTooltip(WrappedComponent, tooltipText) {
183
return function TooltipWrapper(props) {
184
const [showTooltip, setShowTooltip] = useState(false);
185
186
return (
187
<div className="tooltip-container">
188
{cloneElement(<WrappedComponent {...props} />, {
189
onMouseEnter: () => setShowTooltip(true),
190
onMouseLeave: () => setShowTooltip(false)
191
})}
192
{showTooltip && (
193
<div className="tooltip">{tooltipText}</div>
194
)}
195
</div>
196
);
197
};
198
}
199
```
200
201
### isValidElement
202
203
Checks if an object is a valid React element.
204
205
```javascript { .api }
206
/**
207
* Validates if object is a React element
208
* @param object - Object to validate
209
* @returns True if object is a valid React element
210
*/
211
function isValidElement<P>(object: {} | null | undefined): object is ReactElement<P>;
212
```
213
214
**Usage Examples:**
215
216
```javascript
217
import React, { isValidElement } from 'react';
218
219
// Utility function to render different content types
220
function renderContent(content) {
221
if (isValidElement(content)) {
222
// It's a React element, render as-is
223
return content;
224
} else if (typeof content === 'string') {
225
// It's a string, wrap in paragraph
226
return <p>{content}</p>;
227
} else if (typeof content === 'function') {
228
// It's a function, call it
229
return renderContent(content());
230
} else {
231
// Convert to string
232
return <span>{String(content)}</span>;
233
}
234
}
235
236
// Flexible card component
237
function Card({ title, content, footer }) {
238
return (
239
<div className="card">
240
<div className="card-header">
241
{isValidElement(title) ? title : <h3>{title}</h3>}
242
</div>
243
<div className="card-body">
244
{renderContent(content)}
245
</div>
246
{footer && (
247
<div className="card-footer">
248
{isValidElement(footer) ? footer : <p>{footer}</p>}
249
</div>
250
)}
251
</div>
252
);
253
}
254
255
// Usage with different content types
256
<Card
257
title={<h2 className="custom-title">Special Title</h2>}
258
content={<div>Custom JSX content</div>}
259
footer="Simple string footer"
260
/>
261
262
<Card
263
title="String title"
264
content="String content"
265
footer={<button>Action Button</button>}
266
/>
267
268
// Conditional rendering helper
269
function ConditionalWrapper({ condition, wrapper, children }) {
270
if (condition && isValidElement(wrapper)) {
271
return React.cloneElement(wrapper, {}, children);
272
}
273
return children;
274
}
275
276
// Usage
277
<ConditionalWrapper
278
condition={isLoggedIn}
279
wrapper={<div className="authenticated-content" />}
280
>
281
<UserDashboard />
282
</ConditionalWrapper>
283
284
// Type-safe children processing
285
function ProcessChildren({ children, processor }) {
286
return (
287
<div>
288
{React.Children.map(children, (child) => {
289
if (isValidElement(child)) {
290
return processor ? processor(child) : child;
291
}
292
// Handle non-element children (strings, numbers, etc.)
293
return <span key={Math.random()}>{child}</span>;
294
})}
295
</div>
296
);
297
}
298
299
// Filter and process valid React elements
300
function ElementFilter({ children, filter }) {
301
const validElements = React.Children.toArray(children).filter(child =>
302
isValidElement(child) && (!filter || filter(child))
303
);
304
305
return <>{validElements}</>;
306
}
307
308
// Usage - only render Button components
309
<ElementFilter filter={(child) => child.type === Button}>
310
<Button>Valid</Button>
311
<div>This will be filtered out</div>
312
<Button>Also valid</Button>
313
Some text will also be filtered out
314
</ElementFilter>
315
```
316
317
### createFactory
318
319
Creates a factory function for creating elements of a specific type (deprecated but still available).
320
321
```javascript { .api }
322
/**
323
* Creates element factory function for specific type (deprecated)
324
* @param type - Component type or HTML tag name
325
* @returns Factory function that creates elements of the specified type
326
*/
327
function createFactory<P extends {}>(type: string | ComponentType<P>):
328
(props?: (Attributes & P) | null, ...children: ReactNode[]) => ReactElement<P>;
329
```
330
331
**Usage Examples:**
332
333
```javascript
334
import React, { createFactory } from 'react';
335
336
// Create factories for common elements
337
const div = createFactory('div');
338
const h1 = createFactory('h1');
339
const button = createFactory('button');
340
341
// Create factory for custom component
342
function MyComponent({ title, children }) {
343
return <div><h2>{title}</h2>{children}</div>;
344
}
345
const myComponent = createFactory(MyComponent);
346
347
// Usage (equivalent to createElement calls)
348
const element1 = div({ className: 'container' },
349
h1(null, 'Title'),
350
button({ onClick: handleClick }, 'Click me')
351
);
352
353
const element2 = myComponent({ title: 'Section' }, 'Content here');
354
355
// Pre-bound factory with common props
356
function createButtonFactory(defaultProps) {
357
const buttonFactory = createFactory('button');
358
return (props, ...children) => buttonFactory({
359
...defaultProps,
360
...props
361
}, ...children);
362
}
363
364
const primaryButton = createButtonFactory({
365
className: 'btn btn-primary',
366
type: 'button'
367
});
368
369
// Usage
370
const saveButton = primaryButton({ onClick: handleSave }, 'Save');
371
const cancelButton = primaryButton({ onClick: handleCancel }, 'Cancel');
372
```
373
374
## Types
375
376
```javascript { .api }
377
// React element interface
378
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
379
type: T;
380
props: P;
381
key: Key | null;
382
}
383
384
// Element creation types
385
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
386
type Key = string | number;
387
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
388
389
// Props with standard attributes
390
interface Attributes {
391
key?: Key | null;
392
}
393
394
interface RefAttributes<T> extends Attributes {
395
ref?: Ref<T>;
396
}
397
398
interface ClassAttributes<T> extends Attributes {
399
ref?: LegacyRef<T>;
400
}
401
402
// HTML and SVG element types
403
interface ReactHTML {
404
a: DetailedHTMLFactory<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;
405
div: DetailedHTMLFactory<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
406
button: DetailedHTMLFactory<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
407
// ... all other HTML elements
408
}
409
410
interface ReactSVG {
411
svg: SVGFactory;
412
circle: SVGFactory;
413
path: SVGFactory;
414
// ... all other SVG elements
415
}
416
```