[Button | Text] resolvedProps do not update when resolved pattern's props are added/deleted
bashunaimiroy opened this issue · comments
Bug description
tldr
When you add or delete properties in a Pattern, components that use that pattern will not update to reflect the Pattern's new definition. You can partially fix this by initialising properties as undefined
, but the bug still occurs when resetting, i.e. setting the value from anything back to undefined
.
Setup:
In my theme, I'm defining a primary
pattern for Button and buttonPrimary
pattern for Text.
The primary
button pattern has textPattern: 'buttonPrimary'
.
On my page, I have a single MButton with pattern="primary"
.
I also expose controls that change the values in the button and text patterns. If a pattern doesn't already have a prop, I'll add it- e.g. I have an Italic button that toggles fontStyle: 'italic'
on and off in the buttonPrimary
text pattern.
Result
On initial page load, all of the properties in both MButton and the inner MText are resolved to the value of the props defined in their respective patterns. E.g. if I have fontSize: '20px'
in the text pattern, the MText has resolvedFontSize: '20px'
. So far so good.
Example screenshot. $0.__vue__
is an MText instance here. Note that the buttonPrimary
pattern has just had fontStyle: 'italic'
added to it. Also note that the MText's fontStyle
prop is undefined, we're not passing anything into it.
Reproduction
- In the Theme Object, define a pattern for Button. It can be an empty object.
- Create an MButton instance with that pattern
- Confirm that the MButton renders according to the theme default, i.e. no pattern-specific styles
- Add any prop to that pattern, e.g.
color
- Observe that the MButton doesn't render according to the new color prop's value
- Inspect the MButton's
resolvedColor
value and observe that it hasn't changed
Environment
System:
OS: macOS 12.6
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 1.28 GB / 64.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 12.16.2 - ~/.nvm/versions/node/v12.16.2/bin/node
npm: 6.14.4 - ~/.nvm/versions/node/v12.16.2/bin/npm
Addressed by
No response
Can you contribute a fix?
I don't have a fix for Maker, but on my side a partial fix is to define every possible property in my patterns, and simply pass undefined
if I have no value for that property. This way I'm never adding or deleting a property from any pattern. This isn't ideal, but it works. It might be good to mention this in Maker Docs, if no fix is possible
Note: This only fixes it one-way; setting it from undefined
to another value does cause the component to update, but setting it from another value back to undefined
doesn't cause the component to update. E.g. if I have fontStyle: undefined
in my text pattern, and I update to fontStyle: 'italic'
, the component updates. If I then set it back to fontStyle: undefined
, the component remains italicised, with resolvedFontStyle: 'italic'
.
I could work around this by setting it to 'inherit' or some other default value, but this seems bug-prone because I'd be guessing at the default values and anyways I want to fall back to the component's theme props (e.g. if theme.button.patterns.primary.fontStyle
is undefined, I want to fall back to theme.button.fontStyle
). I'd rather leave them undefined
and have Maker resolve them to the component props or default values.
Thoughts
I'm guessing this has to do with the way Vue sets up the watchers. Maybe Vue.set / Vue.delete
would fix this too
I don't have a fix for Maker, but on my side a partial fix is to define every possible property in my patterns, and simply pass
undefined
if I have no value for that property. This way I'm never adding or deleting a property from any pattern. This isn't ideal, but it works. It might be good to mention this in Maker Docs, if no fix is possible.
This is the workaround for a well-known reactivity pitfall/bug within Vue 2.x. There's nothing we can do within Maker to fix a foundational Vue bug. I can experiment with workarounds internally within Maker to potentially ease the burden on Maker users, but for the time being you're likely going to have to stick to toggling prop values between undefined
and defined values instead of adding/removing the prop.
Note: This only fixes it one-way; setting it from
undefined
to another value does cause the component to update, but setting it from another value back to undefined doesn't cause the component to update. E.g. if I havefontStyle: undefined
in my text pattern, and I update tofontStyle: 'italic'
, the component updates. If I then set it back tofontStyle: undefined
, the component remains italicised, withresolvedFontStyle: 'italic'
.
I'll look into this, this might be fixable within Maker.
Toggling between undefined
and some defined value... doesn't seem to be fixable within Maker :/
However, I found another workaround! Instead of toggling between undefined
and some defined value you can toggle between null
and some defined value. Maker's theming system treats all undefined
and null
values identically so they're safely interchangeable, except that undefined
seems to dodge Vue's reactivity triggers, so you have to explicitly set null
when you want to "delete" or "clear" some prop value.
This issue has been automatically closed because it hasn't received any activity in over 6 months.