Skip to content

Commit 2d3518c

Browse files
author
Bob Fanger
committed
fix: React isn't ESM, changed imports for compatibility
1 parent 0124340 commit 2d3518c

File tree

19 files changed

+501
-750
lines changed

19 files changed

+501
-750
lines changed

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"type": "git",
1111
"url": "https://github.com/bfanger/svelte-preprocess-react.git"
1212
},
13-
"version": "0.11.0",
13+
"version": "0.12.0",
1414
"license": "MIT",
1515
"type": "module",
1616
"scripts": {
@@ -68,7 +68,6 @@
6868
"eslint-plugin-only-warn": "^1.0.3",
6969
"eslint-plugin-prettier": "^4.2.1",
7070
"eslint-plugin-svelte3": "^4.0.0",
71-
"happy-dom": "^6.0.4",
7271
"husky": "^8.0.1",
7372
"lint-staged": "^13.0.3",
7473
"postcss": "^8.4.16",
@@ -84,7 +83,7 @@
8483
"typescript": "^4.7.4",
8584
"vite": "^3.0.6",
8685
"vite-tsconfig-paths": "^3.5.0",
87-
"vitest": "^0.23.2"
86+
"vitest": "^0.24.3"
8887
},
8988
"dependencies": {
9089
"magic-string": "^0.26.2"

src/lib/hooks.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { createElement } from "react";
1+
import * as React from "react";
22
import { writable, type Readable } from "svelte/store";
33
import type ReactDOMServer from "react-dom/server";
44
import { getContext, onDestroy } from "svelte";
@@ -42,15 +42,15 @@ function standalone(
4242
if (!renderToString) {
4343
throw new Error("renderToString parameter is required for SSR");
4444
}
45-
renderToString(createElement(Hook));
45+
renderToString(React.createElement(Hook));
4646
return () => {};
4747
}
4848
const el = document.createElement("react-hooks");
4949
const root = ReactDOMClient.createRoot?.(el);
5050
if (root) {
51-
root.render(createElement(Hook));
51+
root.render(React.createElement(Hook));
5252
} else {
53-
ReactDOMClient.render(createElement(Hook), el);
53+
ReactDOMClient.render(React.createElement(Hook), el);
5454
}
5555
return () => {
5656
if (root) {

src/lib/internal/Bridge.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import type React from "react";
2-
import { createElement } from "react";
1+
import * as React from "react";
32
import useStore from "../useStore.js";
43
import SvelteToReactContext from "./SvelteToReactContext.js";
54
import Child from "./Child.js";
@@ -23,7 +22,7 @@ const Bridge: React.FC<BridgeProps> = ({ createPortal, node }) => {
2322
return null;
2423
}
2524
const children: React.ReactElement[] = node.nodes.map((subnode) => {
26-
return createElement(Bridge, {
25+
return React.createElement(Bridge, {
2726
key: subnode.key,
2827
createPortal,
2928
node: subnode,
@@ -35,18 +34,18 @@ const Bridge: React.FC<BridgeProps> = ({ createPortal, node }) => {
3534
delete props.children;
3635
}
3736
if (slot) {
38-
children.push(createElement(Child, { key: "svelte-slot", el: slot }));
37+
children.push(React.createElement(Child, { key: "svelte-slot", el: slot }));
3938
}
4039
if (hooks.length >= 0) {
4140
children.push(
42-
...hooks.map(({ Hook, key }) => createElement(Hook, { key }))
41+
...hooks.map(({ Hook, key }) => React.createElement(Hook, { key }))
4342
);
4443
}
4544
return createPortal(
46-
createElement(
45+
React.createElement(
4746
SvelteToReactContext.Provider,
4847
{ value: node.svelteInstance },
49-
createElement(node.reactComponent, props, children)
48+
React.createElement(node.reactComponent, props, children)
5049
),
5150
target
5251
);

src/lib/internal/Child.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { useRef, useEffect, createElement, type FC } from "react";
1+
import * as React from "react";
22

33
type Props = {
44
el: HTMLElement | undefined;
55
};
6-
const Child: FC<Props> = ({ el }) => {
7-
const ref = useRef<HTMLElement>();
8-
useEffect(() => {
6+
const Child: React.FC<Props> = ({ el }) => {
7+
const ref = React.useRef<HTMLElement>();
8+
React.useEffect(() => {
99
if (!ref.current) {
1010
return;
1111
}
@@ -15,7 +15,7 @@ const Child: FC<Props> = ({ el }) => {
1515
ref.current.appendChild(el);
1616
}
1717
}, [ref, el]);
18-
return createElement("react-child", {
18+
return React.createElement("react-child", {
1919
ref,
2020
style: { display: "contents" },
2121
});

src/lib/internal/ReactWrapper.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
import { writable } from "svelte/store";
33
import { beforeUpdate, getContext, onDestroy, setContext } from "svelte";
44
import type { SvelteInit, TreeNode } from "./types";
5-
import type React from "react";
5+
import type { FunctionComponent } from "react";
66
77
export let svelteInit: (options: SvelteInit) => TreeNode;
88
99
const props = writable<Record<string, any>>(extractProps($$props));
1010
const target = writable<HTMLElement | undefined>();
1111
const slot = writable<HTMLElement | undefined>();
12-
const hooks = writable<Array<{ Hook: React.FC; key: number }>>([]);
12+
const hooks = writable<Array<{ Hook: FunctionComponent; key: number }>>([]);
1313
const listeners: Array<() => void> = [];
1414
1515
const parent = getContext<TreeNode | undefined>("ReactWrapper");
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { createContext } from "react";
1+
import * as React from "react";
22

3-
const SvelteToReactContext = createContext(undefined as any);
3+
const SvelteToReactContext = React.createContext(undefined as any);
44
SvelteToReactContext.displayName = "SvelteToReactContext";
55
export default SvelteToReactContext;

src/lib/internal/types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type React from "react";
21
import type { ComponentClass, FunctionComponent } from "react";
32
import type { Readable, Writable } from "svelte/store";
43

@@ -55,7 +54,7 @@ export type TreeNode = Omit<SvelteInit, "onDestroy"> & {
5554
svelteInstance: Readable<any>;
5655
reactComponent: FunctionComponent<any> | ComponentClass<any>;
5756
key: number;
58-
hooks: Writable<Array<{ Hook: React.FC; key: number }>>;
57+
hooks: Writable<Array<{ Hook: FunctionComponent; key: number }>>;
5958
nodes: TreeNode[];
6059
};
6160

@@ -64,6 +63,6 @@ export type SvelteInit = {
6463
props: Readable<Record<string, any>>;
6564
target: Readable<HTMLElement | undefined>;
6665
slot: Readable<HTMLElement | undefined>;
67-
hooks: Writable<Array<{ Hook: React.FC; key: number }>>;
66+
hooks: Writable<Array<{ Hook: FunctionComponent; key: number }>>;
6867
onDestroy: (callback: () => void) => void;
6968
};

src/lib/preprocessReact.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ function replaceReactTags(
167167
}
168168
}
169169
tag.attributes.forEach((attr) => {
170-
if (attr.type === "EventHandler") {
170+
if (attr.type === "EventHandler" && attr.expression !== null) {
171171
const event = attr as Transition;
172172
if (event.modifiers.length > 0) {
173173
throw new Error(

src/lib/reactify.ts

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import {
2-
createElement,
3-
useContext,
4-
useEffect,
5-
useRef,
6-
type ReactNode,
7-
} from "react";
8-
import type { FunctionComponent } from "react";
1+
import * as React from "react";
92
import { get, type Readable } from "svelte/store";
103
import SvelteWrapper from "./internal/SvelteWrapper.svelte";
114
import SvelteToReactContext from "./internal/SvelteToReactContext.js";
@@ -24,23 +17,23 @@ export type SvelteConstructor<Props = any, Events = any, Slot = any> = {
2417
*/
2518
export default function reactify<P = any, E = any>(
2619
SvelteComponent: SvelteConstructor<P, E>
27-
): FunctionComponent<P & SvelteEventHandlers<E>> {
20+
): React.FunctionComponent<P & SvelteEventHandlers<E>> {
2821
const { name } = SvelteComponent as any;
2922
const named = {
3023
[name](options: any) {
3124
const { children } = options;
3225
const props = extractProps(options);
3326
const events = extractListeners(options);
3427

35-
const wrapperRef = useRef<HTMLElement>();
36-
const svelteRef = useRef<SvelteWrapper>();
37-
const slotRef = useRef<HTMLElement>();
38-
const childrenRef = useRef<HTMLElement>();
28+
const wrapperRef = React.useRef<HTMLElement>();
29+
const svelteRef = React.useRef<SvelteWrapper>();
30+
const slotRef = React.useRef<HTMLElement>();
31+
const childrenRef = React.useRef<HTMLElement>();
3932

40-
const context = useContext(SvelteToReactContext);
33+
const context = React.useContext(SvelteToReactContext);
4134

4235
// Mount Svelte component
43-
useEffect(() => {
36+
React.useEffect(() => {
4437
const target = wrapperRef.current;
4538
if (!target) {
4639
return undefined;
@@ -71,14 +64,14 @@ export default function reactify<P = any, E = any>(
7164
}, [wrapperRef]);
7265

7366
// Sync props & events
74-
useEffect(() => {
67+
React.useEffect(() => {
7568
if (svelteRef.current) {
7669
svelteRef.current.$set({ props, events });
7770
}
7871
}, [props, svelteRef]);
7972

8073
// Sync children/slot
81-
useEffect(() => {
74+
React.useEffect(() => {
8275
if (childrenRef.current) {
8376
if (
8477
slotRef.current &&
@@ -101,22 +94,22 @@ export default function reactify<P = any, E = any>(
10194
context: extractSvelteContext(context),
10295
$$slots,
10396
});
104-
return createElement("svelte-wrapper", {
97+
return React.createElement("svelte-wrapper", {
10598
style: {
10699
display: "contents",
107100
},
108101
dangerouslySetInnerHTML: { __html: result.html },
109102
});
110103
}
111104

112-
return createElement(
105+
return React.createElement(
113106
"svelte-wrapper",
114107
{
115108
ref: wrapperRef,
116109
style: { display: "contents" },
117110
},
118111
children
119-
? createElement(
112+
? React.createElement(
120113
"react-children",
121114
{
122115
ref: childrenRef,
@@ -164,7 +157,7 @@ function extractSvelteContext(reactContext: Readable<any> | undefined) {
164157
}
165158

166159
function detectChildren(
167-
children: ReactNode | ReactNode[] | undefined
160+
children: React.ReactNode | React.ReactNode[] | undefined
168161
): boolean {
169162
if (children === undefined) {
170163
return false;

src/lib/sveltify.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { createElement } from "react";
2-
import type { ComponentClass, FunctionComponent } from "react";
1+
import * as React from "react";
32
import type { SvelteComponentTyped } from "svelte/internal";
43
import type ReactDOMServer from "react-dom/server";
54
import { writable, type Readable } from "svelte/store";
@@ -32,7 +31,7 @@ declare type Sveltified<P extends Record<string, any>> = new (args: {
3231
* Convert a React component into a Svelte component.
3332
*/
3433
export default function sveltify<P>(
35-
reactComponent: FunctionComponent<P> | ComponentClass<P>,
34+
reactComponent: React.FunctionComponent<P> | React.ComponentClass<P>,
3635
createPortal: BridgeProps["createPortal"],
3736
ReactDOMClient: any,
3837
renderToString?: typeof ReactDOMServer.renderToString
@@ -55,14 +54,17 @@ export default function sveltify<P>(
5554
}
5655
const html = $$render.call(Slot, result, {}, bindings, slots, context);
5756
const vdom = html
58-
? createElement(
59-
reactComponent as FunctionComponent,
57+
? React.createElement(
58+
reactComponent as React.FunctionComponent,
6059
props,
61-
createElement("svelte-slot", {
60+
React.createElement("svelte-slot", {
6261
dangerouslySetInnerHTML: { __html: html },
6362
})
6463
)
65-
: createElement(reactComponent as FunctionComponent, props);
64+
: React.createElement(
65+
reactComponent as React.FunctionComponent,
66+
props
67+
);
6668
return renderToString(vdom);
6769
},
6870
} as any;
@@ -76,11 +78,11 @@ export default function sveltify<P>(
7678
document.head.appendChild(targetEl);
7779
if (root) {
7880
rerender = (props: BridgeProps) => {
79-
root.render(createElement(Bridge, props));
81+
root.render(React.createElement(Bridge, props));
8082
};
8183
} else {
8284
rerender = (props: BridgeProps) => {
83-
ReactDOMClient.render(createElement(Bridge, props), rootEl);
85+
ReactDOMClient.render(React.createElement(Bridge, props), rootEl);
8486
};
8587
}
8688
}

0 commit comments

Comments
 (0)