#How would I deep merge two MantineThemes?

70 messages · Page 1 of 1 (latest)

final bronze
#

Hi, I'm wondering how I would deep merge 2 MantineThemes? Is there a simple way to do it? Maybe a function that is exposed that I don't know of?

kind atlas
#

are these custom themes you've made?

final bronze
#

Ehm, if I understand correctly, then yes. The idea is to provide an interface for users to provide their own theme, while providing a default theme.

#

*creating our own library on top of mantine

kind atlas
#

you could possibly use Object.assign() to copy the user themes over the original theme object

#

you might need nested copying, there's some solutions for that

final bronze
#

Hm, I was wondering, if there is an interface or an approach that you use internally.

kind atlas
#

this is the interface definition

final bronze
#

Or is this only a shallow merge? I can look into it myself though.

kind atlas
#

yes, that is one way of doing it

#

your outermost mantineprovider can be the default theme

#

you can then have an inner mantineprovider that provides overrides

final bronze
#

I was wondering how it is done there, is that a shallow merge?

#

Sec, I'll check...

final bronze
#

this doesn't seem to be exposed

#

This won't be exposed I guess? I could copy paste the code...

kind atlas
#

it is exposed

#

but, you likely do not need to do it this way

#

you could simply follow this

#

have an outermost provider with default theme, then an innermost provider with overrides

final bronze
#

If I look into the code, what it does is a shallow copy, no?

#
  const mergedTheme = mergeThemeWithFunctions(
    DEFAULT_THEME,
    inherit ? { ...ctx.theme, ...theme } : theme
  );
kind atlas
final bronze
#

The deep merge is used with the internal DEFAULT_THEME

kind atlas
#

DEFAULT_THEME is the base of all themes, yes

final bronze
#

Yes, what you suggested regarding inherit only works with shallow copy. Meaning, if there is a theme on the child, it will shallow copy it.

kind atlas
#

i do not follow

#

your use case seems to be that you want a base theme, and secondary theme options that override it

#

yes, DEFAULT_THEME is the base of all themes

#

but that is overlooking the line immediately below it

#

inherit ? { ...ctx.theme, ...theme } : theme

#

which is saying

final bronze
#

Yes

#

I can read it.

kind atlas
#

if inherit is set to true, merge the theme context with whatever theme params are provided

final bronze
#

I can only repeat, it is a shallow merge*.

#

I have to use mergeThemeWithFunctions which is not exposed

#

In other words, if I have a theme and now another otherTheme is provided, what inherit essentially does is a shallow merge of the both. Meaning, if there is a components property on otherTheme with a nested object, let's say Tooltip: {styles: ....}, this will override ALL components in theme, right?

#

This is what I want to avoid, but rather merge Tooltip: { styles: ...} into the existing theme. Not overwrite components....

#

Do you know what I mean? Might be I'm not clear enough 🤐

#

I just had a look into the merge-theme module. This covers only one level of nesting:

acc[key] =
      typeof themeOverride[key] === 'object'
        ? { ...currentTheme[key], ...themeOverride[key] }
        : typeof themeOverride[key] === 'number' || typeof themeOverride[key] === 'boolean'
        ? themeOverride[key]
        : themeOverride[key] || currentTheme[key];
    return acc;
#

The key part being: typeof themeOverride[key] === 'object' ? { ...currentTheme[key], ...themeOverride[key] }

ember hare
#

You don't need all of lodash either. You can install each function as a separate module. lodash.mergewith

fierce arch
#

Basically you have 3 themes, Default Mantine Theme, Your Base App Theme, User Defined Theme is that it?

#

I think you could just merge your Base App Theme + User Defined Theme at MantineProvider level, with something like mantine internal mergeThemeWithFunctions, immutability helper, or something similar

final bronze
final bronze
thorn elk
#

isn't that just

#

theme={{ { // custom theme }, ...DEFAULT_THEME }}?

#

it will fill in the missing things a user might not provide

#

or missing peaces

native oar
#

I use this lib for deep merging in typescript
https://www.npmjs.com/package/ts-deepmerge

#

It works well for merging theme data together.
I've created some MUI projects (similar themeing) where I broke up the theme into sections. Colors, typography, components, etc... along with dark and light adjustments and then just merged to the final.
It can help with a larger team on some organization and reduce git conflicts.

#

@final bronze 👆

final bronze
# thorn elk it will fill in the missing things a user might not provide

If you read above, the approach is the other way around. There is already a theme and the user should be able to provide his own theme. What you suggest is, as I mentioned above, a shallow copy, which might overwrite too much...

One could delegate the problem to the developer, but that is what I want to avoid. It adds a complexity layer, which imo leads to bad developer experience.

final bronze
ember hare
#

How often in your code are you doing this that you need improved DX over something like lodash mergeWith or just rolling your own function to deep merge? Even then you just end up w/ your own function that is deepMerge and then you've matched the dev experience of it being baked into Mantine

final bronze
# ember hare How often in your code are you doing this that you need improved DX over somethi...

Regarding your question: It feels like you understood, that I want to go with my own deepMerge implementation which will provide a better user experience than lodash's deepMerge. I don't know where I said something like that?

We could discuss, what I would do in detail, but that is unrelated to the initial question, which literally is asking if there is a simple(suggested) way/exisiting api to do it.

Regarding the rest, i don't quite understand what you are saying. You mean deeply merging won't give me any benefits over the functionality mantine provides (baked in)? What functionality provided by mantine* are you talking about?

final bronze
#

@ember hare friendly ping: What functionality provided by mantine are you talking about?

delicate garden
#

I think his point was just that why would you need a deepMerge function with improved functionality (in this case, better TS support) over just using lodash' or a self-written one.

Either way this thread seems extremely long for what should've just been a simple answer:

Use a utility function that does it for you, whether that be from lodash, or ts-deepmerge or something else, it doesn't matter

kind atlas
#

yup