Skip to content
This repository was archived by the owner on Apr 19, 2021. It is now read-only.

Commit 587f974

Browse files
committed
feat: add reference option
1 parent 5e990fb commit 587f974

File tree

4 files changed

+40
-10
lines changed

4 files changed

+40
-10
lines changed

Diff for: global.d.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ type Assign<T, K> = Pick<T, Exclude<keyof T, keyof K>> & K;
22

33
declare namespace JSX {
44
type Element = Node;
5+
type Reference<T extends keyof HTMLElementTagNameMap = keyof HTMLElementTagNameMap> = {
6+
value?: HTMLElementTagNameMap[T];
7+
};
58
interface ElementChildrenAttribute {
69
children: any;
710
}
811
type IntrinsicElements = {
912
[id in keyof HTMLElementTagNameMap]: Assign<
1013
Partial<HTMLElementTagNameMap[id]>,
11-
{ children?: any }
14+
{ children?: any; ref?: Reference<id> }
1215
>
1316
};
1417
}

Diff for: index.ts

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
11
/// <reference path="global.d.ts" />
22

3-
export type Properties<P> = P & { children?: any };
3+
export type Properties<P> = P & { children?: any; ref?: JSX.Reference };
44
export interface FunctionElement<P> {
55
(props: Properties<P>): JSX.Element;
66
}
77

8-
export function createElement<T extends keyof HTMLElementTagNameMap, L>(
8+
export function createElement<T extends keyof JSX.IntrinsicElements, L>(
99
name: T | FunctionElement<L>,
10-
props: HTMLElementTagNameMap[T] | L,
10+
props: (JSX.IntrinsicElements[T]) | L,
1111
...children: any[]
1212
) {
1313
if (typeof name === "string") {
14+
const { ref, ...rest } = (props || {}) as JSX.IntrinsicElements[T];
1415
const el = document.createElement(name);
15-
Object.assign(el, props);
16+
Object.assign(el, rest);
1617
el.append(...flat(children));
18+
if (ref) {
19+
ref.value = el;
20+
}
21+
return el;
22+
} else {
23+
const { ref, ...rest } = (props || {}) as L & { ref?: any };
24+
const el = name({ ...(rest as L), children });
25+
if (ref) {
26+
ref.value = el;
27+
}
1728
return el;
1829
}
19-
return name({ ...(props as L), children });
2030
}
2131

2232
function flat(arr: any[]): any[] {

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"clean": "rm -f index.js index.d.ts test.js test.d.ts",
1414
"build": "tsc",
1515
"release": "standard-version",
16-
"prepublish": "npm test && npm run build",
16+
"prepublish": "npm run clean && npm test && npm run build",
1717
"test": "jest"
1818
},
1919
"jest": {

Diff for: test.tsx

+20-3
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,25 @@ global.document = {
1515
};
1616

1717
test("jsx", () => {
18-
expect(<div>hello</div>).toMatchObject({
18+
const ref: JSX.Reference<"h1"> = {};
19+
expect(
20+
<div>
21+
<h1 ref={ref}>hello</h1>
22+
</div>
23+
).toMatchObject({
1924
name: "div",
20-
children: ["hello"]
25+
children: [{ name: "h1", children: ["hello"] }]
2126
});
27+
expect(ref.value).toMatchObject({ name: "h1", children: ["hello"] });
2228
});
2329

2430
test("function", () => {
2531
function Layout(props: any) {
2632
return <div className="container">{props.children}</div>;
2733
}
34+
const ref: JSX.Reference<"div"> = {};
2835
expect(
29-
<Layout>
36+
<Layout ref={ref}>
3037
<h1>hello</h1>
3138
</Layout>
3239
).toMatchObject({
@@ -39,4 +46,14 @@ test("function", () => {
3946
}
4047
]
4148
});
49+
expect(ref.value).toMatchObject({
50+
name: "div",
51+
className: "container",
52+
children: [
53+
{
54+
name: "h1",
55+
children: ["hello"]
56+
}
57+
]
58+
});
4259
});

0 commit comments

Comments
 (0)