square / maker

Maker Design System by Square
https://square.github.io/maker/styleguide/latest-stable/
Other
63 stars 14 forks source link

Theme bug: profiles definitions in nested themes merged incorrectly #350

Closed laurenhu closed 2 years ago

laurenhu commented 2 years ago

Bug description

When the MTheme resolveTheme function is merging its theme prop with parent themes, profiles are being merged in index order without regard to their id. This could also result in profiles with unexpected properties as well as defaultProfile being overwritten if a nested <m-theme :theme="defaultTheme()"> is used.

In the following situation:

<m-theme :theme="{ profiles: [{ id: 'profile-one', colors: { background: 'red' } }] }>
    <m-theme :theme="{ profiles: [{ id: 'defaultProfile' }] }"></mtheme>
</m-theme>

this is the data on the inner MTheme:

profiles: [
    {
        id: 'defaultProfile',
        colors:  { background: 'red' },
    }
]

Reproduction

Nest a Mtheme component with theme.profiles definitions inside another Mtheme component with different theme.profiles definitions.

Environment

All

Addressed by

No response

Can you contribute a fix?

pretzelhammer commented 2 years ago

assuming we're matching profiles by their ids, how should they be merged? should they be merged together recursively OR should the latter defined profile completely override the formerly defined profile?

Follow-up question: is there a reason we made profiles into an array with profile definition objects with id fields instead of making it into an object where the keys are the ids and the values are the profile definition objects? i.e.

{ profiles: [
    {id: 'default-profile', colors: { /* whatever */ }},
    {id: 'profile-one', colors: { /* whatever */ }}
]}

vs

{ profiles: {
    'default-profile': { colors: { /* whatever */ }},
    'profile-one': { colors: { /* whatever */ }},
}}

???

pretzelhammer commented 2 years ago

notes from our slack huddle: