Skip to content

Commit 6f3abdf

Browse files
committed
✨ New release
1 parent 01c037f commit 6f3abdf

File tree

3 files changed

+25
-26
lines changed

3 files changed

+25
-26
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "r2wc",
3-
"version": "0.0.2",
3+
"version": "0.0.3",
44
"license": "MIT",
55
"keywords": [
66
"React",

src/core.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,18 @@ export default function r2wc<Props, Context>(
6464
}
6565

6666
class ReactWebComponent extends HTMLElement {
67-
static get observedAttributes() {
68-
return Object.keys(mapAttributeProp);
69-
}
70-
71-
private connected = true;
67+
private connected = false;
7268
private context?: Context;
7369
props: Props = {} as Props;
7470
container: HTMLElement;
71+
observer: MutationObserver;
7572

7673
constructor() {
7774
super();
75+
this.observer = new MutationObserver((mutations) =>
76+
this.attributesChanged(mutations)
77+
);
78+
this.observer.observe(this, { attributes: true });
7879

7980
if (options.shadow) {
8081
this.container = this.attachShadow({
@@ -90,27 +91,26 @@ export default function r2wc<Props, Context>(
9091

9192
connectedCallback() {
9293
this.connected = true;
93-
this.render();
9494

9595
for (const prop of propNames) {
9696
this.setProps(prop);
9797
}
9898

99-
this.update();
99+
this.mount();
100100
}
101101

102102
disconnectedCallback() {
103103
this.connected = false;
104104

105-
if (this.context) {
106-
renderer.unmount(this.context);
107-
}
105+
this.unmount();
108106
}
109107

110-
attributeChangedCallback(attribute: Extract<keyof Props, string>) {
111-
this.setProps(attribute);
108+
private attributesChanged(mutations: MutationRecord[]) {
109+
mutations.forEach(({ attributeName }) => {
110+
this.setProps(attributeName as Extract<keyof Props, string>);
111+
});
112112

113-
this.render();
113+
this.update();
114114
}
115115

116116
private setProps(prop: Extract<keyof Props, string>) {
@@ -125,33 +125,32 @@ export default function r2wc<Props, Context>(
125125
const value = reactProps[prop] ?? this.getAttribute(attribute);
126126
const type = propTypes[prop];
127127
const transform = transforms[type];
128-
if (reactProps[prop]) {
128+
if (prop in reactProps) {
129129
this.props[prop] = value;
130130
} else if (value && transform?.parse) {
131131
//@ts-ignore
132132
this.props[prop] = transform.parse(value, this);
133133
}
134134
}
135135

136-
private render() {
137-
if (!this.connected) return;
138-
139-
if (!this.context) {
140-
this.mount();
141-
} else {
142-
this.update();
143-
}
144-
}
145-
146136
private update() {
137+
if (!this.connected) return;
147138
if (!this.context) return;
148139

149140
renderer.update(this.context, this.props);
150141
}
151142

152143
private mount() {
144+
if (!this.connected) throw new Error(`${ReactComponent} is not in a DOM`);
145+
if (this.context) throw new Error(`${ReactComponent} is already mounted`);
146+
153147
this.context = renderer.mount(this.container, ReactComponent, this.props);
154148
}
149+
150+
private unmount() {
151+
if (!this.context) return;
152+
renderer.unmount(this.context);
153+
}
155154
}
156155

157156
return ReactWebComponent;

0 commit comments

Comments
 (0)