mitosis
mitosis copied to clipboard
Generation of Vue 2 classes could possibly avoid _classStringToObject
I am interested in helping provide a fix!
Yes
Which generators are impacted?
- [ ] All
- [ ] Angular
- [ ] HTML
- [ ] Qwik
- [ ] React
- [ ] React-Native
- [ ] Solid
- [ ] Stencil
- [ ] Svelte
- [X] Vue
- [ ] Web components
Reproduction case
https://mitosis.builder.io/?outputTab=G4VwpkA%3D&inputTab=M4NwpgNgLmQ%3D&code=DwZwxgTglgDgLgPgFAAIUFMAeMD2E4oA26BAJlCAIYBGxpKAvCgGaWEjoDcqRJLOYAK4hGKOBEFckwAPTho8ZNKgA7GIIJhClECAYAiZngC2AWlXq4%2BlFp0gAXOSq109W7vtGhImQiA%3D
Expected Behaviour
The Vue 2 output in the the Class Directive example uses minimal Vue code, e.g.
<input
class="form-input"
:class="{disabled: disabled, focus: focus}"
/>
Actual Behaviour
The Vue 2 output in the Class Directive uses code which is quite verbose, converting a string into a class with a _classStringToObject
helper:
<input
:class="
_classStringToObject(
`form-input ${disabled ? 'disabled' : ''} ${focus ? 'focus' : ''}`
)
"
/>
Additional Information
No response
That's because this is the only way that the JSX syntax works: it has a class
string prop that concatenates everything:
see example
You're right that for the Svelte syntax, and certain simpler cases, we could do away with _classStringToObject()
. I am always open to improving the compiler if it means removing injected code such as this helper.
This would be a fairly involved task however...the class
binding is stored in the Mitosis JSON as a string:
"bindings": {
"class": {
"code": "`form-input ${props.disabled ? \"disabled\" : \"\"} ${state.focus ? \"focus\" : \"\"}`"
}
},
That is the case for both the JSX and Svelte syntaxes. Now, since the Svelte syntax already supports providing separate class bindings, it would be very easy the JSON output of that to something like (very pseudo-code-ish syntax):
"bindings": {
"class": [{
"code": "form-input",
}, {
"object": "props.disabled",
}, {
"object": "state.focus",
}]
},
and then have the Vue generator (and other generators) provide a cleaner output for it.
However, I don't see how we can improve that for the JSX output without introducing a new syntax to support a class
object, e.g.:
import { useStore } from "@builder.io/mitosis";
export default function MyComponent(props) {
const state = useStore({ focus: true });
return (
<input
class="form-input"
class={{
disabled: props.disabled,
focus: state.focus
}}
/>
);
}
But I'd have to think a bit more through:
- whether we want to introduce such a new syntax
- how exactly this syntax should look like (multiple
class
es?class
andclassObj
or something?) - what edge cases might exist when building complex
class
strings