Skip to content

Commit f289863

Browse files
committed
fix: theme props more stable
1 parent da843aa commit f289863

File tree

2 files changed

+49
-32
lines changed

2 files changed

+49
-32
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
'use client';
2+
import * as React from 'react';
23
import getThemeProps from './getThemeProps';
34
import useTheme from '../useTheme';
45

@@ -7,6 +8,5 @@ export default function useThemeProps({ props, name, defaultTheme, themeId }) {
78
if (themeId) {
89
theme = theme[themeId] || theme;
910
}
10-
const mergedProps = getThemeProps({ theme, name, props });
11-
return mergedProps;
11+
return React.useMemo(() => getThemeProps({ theme, name, props }), [theme, name, props]);
1212
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
/* eslint-disable no-restricted-syntax */
2+
13
/**
24
* Add keys, values of `defaultProps` that does not exist in `props`
3-
* @param {object} defaultProps
4-
* @param {object} props
5-
* @returns {object} resolved props
5+
* @param defaultProps
6+
* @param props
7+
* @returns resolved props
68
*/
79
export default function resolveProps<
810
T extends {
@@ -14,36 +16,51 @@ export default function resolveProps<
1416
>(defaultProps: T, props: T) {
1517
const output = { ...props };
1618

17-
(Object.keys(defaultProps) as Array<keyof T>).forEach((propName) => {
18-
if (propName.toString().match(/^(components|slots)$/)) {
19-
output[propName] = {
20-
...(defaultProps[propName] as any),
21-
...(output[propName] as any),
22-
};
23-
} else if (propName.toString().match(/^(componentsProps|slotProps)$/)) {
24-
const defaultSlotProps = (defaultProps[propName] || {}) as T[keyof T];
25-
const slotProps = props[propName] as {} as T[keyof T];
26-
output[propName] = {} as T[keyof T];
19+
for (const key in defaultProps) {
20+
if (Object.prototype.hasOwnProperty.call(defaultProps, key)) {
21+
const propName = key as keyof T;
22+
23+
if (propName === 'components' || propName === 'slots') {
24+
output[propName] = {
25+
...(defaultProps[propName] as any),
26+
...(output[propName] as any),
27+
};
28+
} else if (propName === 'componentsProps' || propName === 'slotProps') {
29+
const defaultSlotProps = defaultProps[propName] as T[keyof T] | undefined;
30+
const slotProps = props[propName] as {} as T[keyof T] | undefined;
31+
32+
if (!slotProps || isObjectEmpty(slotProps)) {
33+
// Reduce the iteration if the slot props is empty
34+
output[propName] = defaultSlotProps || ({} as T[keyof T]);
35+
} else if (!defaultSlotProps || isObjectEmpty(defaultSlotProps)) {
36+
// Reduce the iteration if the default slot props is empty
37+
output[propName] = slotProps;
38+
} else {
39+
output[propName] = { ...slotProps };
2740

28-
if (!slotProps || !Object.keys(slotProps)) {
29-
// Reduce the iteration if the slot props is empty
30-
output[propName] = defaultSlotProps;
31-
} else if (!defaultSlotProps || !Object.keys(defaultSlotProps)) {
32-
// Reduce the iteration if the default slot props is empty
33-
output[propName] = slotProps;
34-
} else {
35-
output[propName] = { ...slotProps };
36-
Object.keys(defaultSlotProps).forEach((slotPropName) => {
37-
(output[propName] as Record<string, unknown>)[slotPropName] = resolveProps(
38-
(defaultSlotProps as Record<string, any>)[slotPropName],
39-
(slotProps as Record<string, any>)[slotPropName],
40-
);
41-
});
41+
for (const slotKey in defaultSlotProps) {
42+
if (Object.prototype.hasOwnProperty.call(defaultSlotProps, slotKey)) {
43+
const slotPropName = slotKey;
44+
(output[propName] as Record<string, unknown>)[slotPropName] = resolveProps(
45+
(defaultSlotProps as Record<string, any>)[slotPropName],
46+
(slotProps as Record<string, any>)[slotPropName],
47+
);
48+
}
49+
}
50+
}
51+
} else if (output[propName] === undefined) {
52+
output[propName] = defaultProps[propName];
4253
}
43-
} else if (output[propName] === undefined) {
44-
output[propName] = defaultProps[propName];
4554
}
46-
});
55+
}
4756

4857
return output;
4958
}
59+
60+
function isObjectEmpty(object: Object) {
61+
// eslint-disable-next-line
62+
for (const _ in object) {
63+
return false;
64+
}
65+
return true;
66+
}

0 commit comments

Comments
 (0)