Skip to content

Commit

Permalink
fix: make theme props more stable
Browse files Browse the repository at this point in the history
  • Loading branch information
romgrk committed Jul 30, 2024
1 parent 8fcc47f commit cee9e21
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 32 deletions.
4 changes: 2 additions & 2 deletions packages/mui-system/src/useThemeProps/useThemeProps.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
'use client';
import * as React from 'react';
import getThemeProps from './getThemeProps';
import useTheme from '../useTheme';

Expand All @@ -7,6 +8,5 @@ export default function useThemeProps({ props, name, defaultTheme, themeId }) {
if (themeId) {
theme = theme[themeId] || theme;
}
const mergedProps = getThemeProps({ theme, name, props });
return mergedProps;
return React.useMemo(() => getThemeProps({ theme, name, props }), [theme, name, props]);
}
77 changes: 47 additions & 30 deletions packages/mui-utils/src/resolveProps/resolveProps.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable no-restricted-syntax */

/**
* Add keys, values of `defaultProps` that does not exist in `props`
* @param {object} defaultProps
* @param {object} props
* @returns {object} resolved props
* @param defaultProps
* @param props
* @returns resolved props
*/
export default function resolveProps<
T extends {
Expand All @@ -14,36 +16,51 @@ export default function resolveProps<
>(defaultProps: T, props: T) {
const output = { ...props };

(Object.keys(defaultProps) as Array<keyof T>).forEach((propName) => {
if (propName.toString().match(/^(components|slots)$/)) {
output[propName] = {
...(defaultProps[propName] as any),
...(output[propName] as any),
};
} else if (propName.toString().match(/^(componentsProps|slotProps)$/)) {
const defaultSlotProps = (defaultProps[propName] || {}) as T[keyof T];
const slotProps = props[propName] as {} as T[keyof T];
output[propName] = {} as T[keyof T];
for (const key in defaultProps) {
if (Object.prototype.hasOwnProperty.call(defaultProps, key)) {
const propName = key as keyof T;

if (propName === 'components' || propName === 'slots') {
output[propName] = {
...(defaultProps[propName] as any),
...(output[propName] as any),
};
} else if (propName === 'componentsProps' || propName === 'slotProps') {
const defaultSlotProps = defaultProps[propName] as T[keyof T] | undefined;
const slotProps = props[propName] as {} as T[keyof T] | undefined;

if (!slotProps || isObjectEmpty(slotProps)) {
// Reduce the iteration if the slot props is empty
output[propName] = defaultSlotProps || ({} as T[keyof T]);
} else if (!defaultSlotProps || isObjectEmpty(defaultSlotProps)) {
// Reduce the iteration if the default slot props is empty
output[propName] = slotProps;
} else {
output[propName] = { ...slotProps };

if (!slotProps || !Object.keys(slotProps)) {
// Reduce the iteration if the slot props is empty
output[propName] = defaultSlotProps;
} else if (!defaultSlotProps || !Object.keys(defaultSlotProps)) {
// Reduce the iteration if the default slot props is empty
output[propName] = slotProps;
} else {
output[propName] = { ...slotProps };
Object.keys(defaultSlotProps).forEach((slotPropName) => {
(output[propName] as Record<string, unknown>)[slotPropName] = resolveProps(
(defaultSlotProps as Record<string, any>)[slotPropName],
(slotProps as Record<string, any>)[slotPropName],
);
});
for (const slotKey in defaultSlotProps) {
if (Object.prototype.hasOwnProperty.call(defaultSlotProps, slotKey)) {
const slotPropName = slotKey;
(output[propName] as Record<string, unknown>)[slotPropName] = resolveProps(
(defaultSlotProps as Record<string, any>)[slotPropName],
(slotProps as Record<string, any>)[slotPropName],
);
}
}
}
} else if (output[propName] === undefined) {
output[propName] = defaultProps[propName];
}
} else if (output[propName] === undefined) {
output[propName] = defaultProps[propName];
}
});
}

return output;
}

function isObjectEmpty(object: Object) {
// eslint-disable-next-line
for (const _ in object) {
return false;
}
return true;
}

0 comments on commit cee9e21

Please sign in to comment.