From eb79cdac61dbe4750d342ac61f033132ac8c9e55 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 14 Dec 2022 17:34:10 +0700 Subject: [PATCH 1/3] merge props --- packages/mui-utils/src/resolveProps.test.ts | 24 +++++++++++++++++++++ packages/mui-utils/src/resolveProps.ts | 20 ++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/mui-utils/src/resolveProps.test.ts b/packages/mui-utils/src/resolveProps.test.ts index eb0b1943284297..1e407ea036fa87 100644 --- a/packages/mui-utils/src/resolveProps.test.ts +++ b/packages/mui-utils/src/resolveProps.test.ts @@ -44,4 +44,28 @@ describe('resolveProps', () => { foo: '', }); }); + + it('merge components and componentsProps props', () => { + expect( + resolveProps( + { components: { Input: 'Input' }, componentsProps: { input: 'input' } }, + { components: { Root: 'Root' }, componentsProps: { root: 'root' } }, + ), + ).to.deep.equal({ + components: { Root: 'Root', Input: 'Input' }, + componentsProps: { root: 'root', input: 'input' }, + }); + }); + + it('merge slots and slotProps props', () => { + expect( + resolveProps( + { slots: { input: 'input' }, slotProps: { input: 'input' } }, + { slots: { root: 'root' }, slotProps: { root: 'root' } }, + ), + ).to.deep.equal({ + slots: { root: 'root', input: 'input' }, + slotProps: { root: 'root', input: 'input' }, + }); + }); }); diff --git a/packages/mui-utils/src/resolveProps.ts b/packages/mui-utils/src/resolveProps.ts index 35d46f9ec35809..3239f13f81ddc0 100644 --- a/packages/mui-utils/src/resolveProps.ts +++ b/packages/mui-utils/src/resolveProps.ts @@ -4,14 +4,24 @@ * @param {object} props * @returns {object} resolved props */ -export default function resolveProps>( - defaultProps: T, - props: T, -) { +export default function resolveProps< + T extends { + className?: string; + components?: Record; + componentsProps?: Record; + slots?: Record; + slotProps?: Record; + } & Record, +>(defaultProps: T, props: T) { const output = { ...props }; Object.keys(defaultProps).forEach((propName: keyof T) => { - if (output[propName] === undefined) { + if (propName.toString().match(/^(components|componentsProps|slots|slotProps)$/)) { + output[propName] = { + ...(defaultProps[propName] as any), + ...(output[propName] as any), + }; + } else if (output[propName] === undefined) { output[propName] = defaultProps[propName]; } }); From 7f90ecfe55fd3d3f4350c1c60a855303a818c366 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Mon, 19 Dec 2022 12:59:30 +0700 Subject: [PATCH 2/3] fix logic to merge slotProps --- packages/mui-utils/src/resolveProps.test.ts | 24 +++++++++++++++----- packages/mui-utils/src/resolveProps.ts | 25 ++++++++++++++++++--- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/packages/mui-utils/src/resolveProps.test.ts b/packages/mui-utils/src/resolveProps.test.ts index 1e407ea036fa87..e2539225498ecd 100644 --- a/packages/mui-utils/src/resolveProps.test.ts +++ b/packages/mui-utils/src/resolveProps.test.ts @@ -48,24 +48,36 @@ describe('resolveProps', () => { it('merge components and componentsProps props', () => { expect( resolveProps( - { components: { Input: 'Input' }, componentsProps: { input: 'input' } }, - { components: { Root: 'Root' }, componentsProps: { root: 'root' } }, + { components: { Input: 'Input' }, componentsProps: { input: { className: 'input' } } }, + { + components: { Root: 'Root' }, + componentsProps: { root: { className: 'root' }, input: { style: { color: 'red' } } }, + }, ), ).to.deep.equal({ components: { Root: 'Root', Input: 'Input' }, - componentsProps: { root: 'root', input: 'input' }, + componentsProps: { + root: { className: 'root' }, + input: { className: 'input', style: { color: 'red' } }, + }, }); }); it('merge slots and slotProps props', () => { expect( resolveProps( - { slots: { input: 'input' }, slotProps: { input: 'input' } }, - { slots: { root: 'root' }, slotProps: { root: 'root' } }, + { slots: { input: 'input' }, slotProps: { input: { className: 'input' } } }, + { + slots: { root: 'root' }, + slotProps: { root: { className: 'root' }, input: { style: { color: 'red' } } }, + }, ), ).to.deep.equal({ slots: { root: 'root', input: 'input' }, - slotProps: { root: 'root', input: 'input' }, + slotProps: { + root: { className: 'root' }, + input: { className: 'input', style: { color: 'red' } }, + }, }); }); }); diff --git a/packages/mui-utils/src/resolveProps.ts b/packages/mui-utils/src/resolveProps.ts index 3239f13f81ddc0..fef2dbdb86f049 100644 --- a/packages/mui-utils/src/resolveProps.ts +++ b/packages/mui-utils/src/resolveProps.ts @@ -6,7 +6,6 @@ */ export default function resolveProps< T extends { - className?: string; components?: Record; componentsProps?: Record; slots?: Record; @@ -15,12 +14,32 @@ export default function resolveProps< >(defaultProps: T, props: T) { const output = { ...props }; - Object.keys(defaultProps).forEach((propName: keyof T) => { - if (propName.toString().match(/^(components|componentsProps|slots|slotProps)$/)) { + (Object.keys(defaultProps) as Array).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]; + + 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)[slotPropName] = resolveProps( + (defaultSlotProps as Record)[slotPropName], + (slotProps as Record)[slotPropName], + ); + }); + } } else if (output[propName] === undefined) { output[propName] = defaultProps[propName]; } From 57130233370d1468d9a2c81549e5df0b0088dc1a Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Mon, 19 Dec 2022 16:00:55 +0700 Subject: [PATCH 3/3] add another tests --- packages/mui-utils/src/resolveProps.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/mui-utils/src/resolveProps.test.ts b/packages/mui-utils/src/resolveProps.test.ts index e2539225498ecd..491428ffc22a3a 100644 --- a/packages/mui-utils/src/resolveProps.test.ts +++ b/packages/mui-utils/src/resolveProps.test.ts @@ -80,4 +80,15 @@ describe('resolveProps', () => { }, }); }); + + it('should not merge props that are not intended', () => { + expect( + resolveProps( + { notTheSlotProps: { style: { color: 'red' } } }, + { notTheSlotProps: { className: 'input' } }, + ), + ).to.deep.equal({ + notTheSlotProps: { className: 'input' }, + }); + }); });