Skip to content

Commit 615cb73

Browse files
added forwardRef to py-config
1 parent 9ade3af commit 615cb73

File tree

4 files changed

+102
-78
lines changed

4 files changed

+102
-78
lines changed

source/library/components/py-box/py-box.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export type PyBoxProperties<OptionalProperties> =
2323
export type PyBoxTag = {
2424
<OptionalProperties extends object>(
2525
properties: PyBoxProperties<OptionalProperties>,
26-
reference: LegacyRef<HTMLElement> | undefined,
26+
reference?: LegacyRef<HTMLElement>,
2727
): JSX.Element;
2828
displayName?: string;
2929
defaultProps?: Partial<PyBoxPropertiesBase>;

source/library/components/py-button/py-button.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type PyButtonProperties<OptionalProperties> =
2424
export type PyButtonTag = {
2525
<OptionalProperties extends object>(
2626
properties: PyButtonProperties<OptionalProperties>,
27-
reference: LegacyRef<HTMLElement> | undefined,
27+
reference?: LegacyRef<HTMLElement>,
2828
): JSX.Element;
2929
displayName?: string;
3030
defaultProps?: Partial<PyButtonPropertiesBase>;

source/library/components/py-config/py-config.tsx

Lines changed: 91 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import propTypes from "prop-types";
2-
import { WeakValidationMap, useEffect, useMemo } from "react";
2+
import {
3+
forwardRef,
4+
useEffect,
5+
useMemo,
6+
type ForwardedRef,
7+
type WeakValidationMap,
8+
} from "react";
39
import type {
410
PyConfigFetch,
511
PyConfigFetchItem,
@@ -37,79 +43,91 @@ const checkForAnyKey = (
3743
* @see {@link https://docs.pyscript.net/latest/reference/elements/py-config.html} Original py-config element documentation.
3844
* @see {@link https://pyscript-react.github.io/} Pyscript-react element documentation.
3945
*/
40-
const PyConfig: PyConfigTag = <T extends object>({
41-
children,
42-
source,
43-
type,
44-
splashscreen,
45-
interpreters,
46-
fetch,
47-
packages,
48-
plugins,
49-
...rest
50-
}: PyConfigProperties<T>): JSX.Element => {
51-
// eslint-disable-next-line sonarjs/cognitive-complexity
52-
const config: string = useMemo((): string => {
53-
if (type === "json") {
54-
const transformedPlugins: string[] = [
55-
...(plugins || []),
56-
...(children?.plugins || []),
57-
];
58-
const transformedPackages: string[] = [
59-
...(packages || []),
60-
...(children?.packages || []),
61-
];
62-
const transformedFetch: PyConfigFetch = [
63-
...(fetch || []),
64-
...(children?.fetch || []),
65-
].map(({ files, ...restItem }: PyConfigFetchItem): PyConfigFetchItem => {
66-
const transformedFiles: string[] = [...(files || [])];
67-
return {
68-
files: transformedFiles.length ? transformedFiles : undefined,
69-
...restItem,
46+
const PyConfig: PyConfigTag = forwardRef(
47+
<T extends object>(
48+
{
49+
children,
50+
source,
51+
type,
52+
splashscreen,
53+
interpreters,
54+
fetch,
55+
packages,
56+
plugins,
57+
...rest
58+
}: PyConfigProperties<T>,
59+
reference: ForwardedRef<HTMLElement> | undefined,
60+
// eslint-disable-next-line max-params, sonarjs/cognitive-complexity
61+
): JSX.Element => {
62+
const config: string = useMemo((): string => {
63+
if (type === "json") {
64+
const transformedPlugins: string[] = [
65+
...(plugins ?? []),
66+
...(children?.plugins ?? []),
67+
];
68+
const transformedPackages: string[] = [
69+
...(packages ?? []),
70+
...(children?.packages ?? []),
71+
];
72+
const transformedFetch: PyConfigFetch = [
73+
...(fetch ?? []),
74+
...(children?.fetch ?? []),
75+
].map(
76+
({ files, ...restItem }: PyConfigFetchItem): PyConfigFetchItem => {
77+
const transformedFiles: string[] = [...(files ?? [])];
78+
return {
79+
files: transformedFiles.length ? transformedFiles : undefined,
80+
...restItem,
81+
};
82+
},
83+
);
84+
const transformedInterpreters: Omit<PyConfigInterpreters, "source"> & {
85+
src?: string;
86+
} = {
87+
src: interpreters?.source,
88+
name: interpreters?.name,
89+
language: interpreters?.language,
90+
...children?.interpreters,
7091
};
71-
});
72-
const transformedInterpreters: Omit<PyConfigInterpreters, "source"> & {
73-
src?: string;
74-
} = {
75-
src: interpreters?.source,
76-
name: interpreters?.name,
77-
language: interpreters?.language,
78-
...children?.interpreters,
79-
};
80-
const transformedSplashscreen: PyConfigSplashscreen = {
81-
autoclose: splashscreen?.autoclose,
82-
...children?.splashscreen,
83-
};
84-
const config: string = JSON.stringify({
85-
splashscreen: checkForAnyKey(transformedSplashscreen)
86-
? transformedSplashscreen
87-
: undefined,
88-
interpreters: checkForAnyKey(transformedInterpreters)
89-
? transformedInterpreters
90-
: undefined,
91-
fetch: transformedFetch.length ? transformedFetch : undefined,
92-
packages: transformedPackages.length ? transformedPackages : undefined,
93-
plugins: transformedPlugins.length ? transformedPlugins : undefined,
94-
...children,
95-
});
96-
return config;
97-
}
98-
return `${children || ""}`;
99-
}, [children, splashscreen, interpreters, fetch, packages, plugins]);
100-
useEffect((): void => {
101-
source &&
102-
children &&
103-
console.warn(
104-
"Children is passed with source. It may create undefined behavior. Remove one of these properties.",
105-
);
106-
}, [source, children]);
107-
return (
108-
<py-config {...rest} type={type} src={source}>
109-
{!source ? config : undefined}
110-
</py-config>
111-
);
112-
};
92+
const transformedSplashscreen: PyConfigSplashscreen = {
93+
autoclose: splashscreen?.autoclose,
94+
...children?.splashscreen,
95+
};
96+
const config: string = JSON.stringify({
97+
splashscreen: checkForAnyKey(transformedSplashscreen)
98+
? transformedSplashscreen
99+
: undefined,
100+
interpreters: checkForAnyKey(transformedInterpreters)
101+
? transformedInterpreters
102+
: undefined,
103+
fetch: transformedFetch.length ? transformedFetch : undefined,
104+
packages: transformedPackages.length
105+
? transformedPackages
106+
: undefined,
107+
plugins: transformedPlugins.length ? transformedPlugins : undefined,
108+
...children,
109+
});
110+
return config;
111+
}
112+
return `${children ?? ""}`;
113+
}, [children, splashscreen, interpreters, fetch, packages, plugins]);
114+
useEffect((): void => {
115+
source &&
116+
children &&
117+
// eslint-disable-next-line no-console
118+
console.warn(
119+
"Children is passed with source. It may create undefined behavior. Remove one of these properties.",
120+
);
121+
}, [source, children]);
122+
return (
123+
<py-config ref={reference} {...rest} type={type} src={source}>
124+
{!source ? config : undefined}
125+
</py-config>
126+
);
127+
},
128+
) as PyConfigTag;
129+
130+
PyConfig.displayName = "PyConfig";
113131

114132
PyConfig.propTypes = {
115133
children: propTypes.oneOfType([

source/library/components/py-config/py-config.types.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import type {
1+
import {
22
DetailedHTMLProps,
33
HTMLAttributes,
4+
LegacyRef,
45
WeakValidationMap,
56
} from "react";
67
import type ReactElementProps from "~types/react-element-properties/react-element-properties";
@@ -78,6 +79,11 @@ export type PyConfigProperties<T> = T extends infer T
7879
: PyConfigPropertiesBase;
7980

8081
export type PyConfigTag = {
81-
<T extends object>(properties: PyConfigProperties<T>): JSX.Element;
82-
propTypes: WeakValidationMap<PyConfigPropertiesBase>;
82+
<T extends object>(
83+
properties: PyConfigProperties<T>,
84+
reference?: LegacyRef<HTMLElement>,
85+
): JSX.Element;
86+
displayName?: string;
87+
defaultProps?: Partial<PyConfigPropertiesBase>;
88+
propTypes?: WeakValidationMap<PyConfigPropertiesBase>;
8389
};

0 commit comments

Comments
 (0)