A project I inherited is using Vue 3 and FormKit for Vue and Tailwind. I would like to make some links that are styled to look like buttons from the FormKit theme. For example, a back/cancel button on the form would be a router-link, not a button or submit, but I want it to look like the other buttons.
The reason this is difficult is because FormKit has a theming system that uses Tailwind and it applies dozens of classes at run time. For example
<FormKit type="button" />
Will generate the following
<button type="button" class="inline-block bg-primary-500 text-white ...">
There are no global styles like a formkit-button and there doesn't seem to be an easy way to get these generated styles and apply them to non <FormKit> elements.
Copying and pasting the generated classes is out of the question because any changes to the theme will not carry over.
Is there any way to either apply FormKit button styles to a router-link, or tell the FormKit button component to render as a router-link?
You can get the classes by passing a mock component to the
rootClassesfunction, which is exported by the theme file (typicallyformkit.theme.[js|ts]):This is how Forkit gets the classes, except that it uses the actual nodes. The returned object looks like this:
You can use it directly in the
:classprop or turn it into a list of strings when necessary:You can also inject the
rootClassesthrough the formkit config:But you'll probably want to keep the formkit element structure, as it impacts appearance. The straight-forward approach would be to override the element of a FormKit button using sections-schema:
Now an
<a>is rendered instead of a<button>. This works without fumbling around with therootClasses, but not with components like RouterLink, and it will also put the button attributes (liketype="button") on the anchor, and you'll have to add the:section-schemaprop on every link button.To use a component, you can define a custom input, where you set your own template and register it with formkit. When setting
family: button, most (but annoyingly not all) button classes are inherited. Here is an example:Now you can use it through the
FormKitcomponent:Internally, formkit passes the component to
rootClasses, which uses thefamilyandtypeprops to resolve the classes (you can explore this in your template file). But sincetypeis not"button"anymore, those classes (for background and hover) are missing.Still, this is probably the "cleanest" approach, i.e. without using
rootClasses, but it needs manual adjustment with the missing classes.To get all
buttonclasses, you have to apply them manually, usingrootClassesas described in the beginning. Here is an example withRouterLink:This can be registered and used as above.
Here is a sandbox with the examples. Hope it helps!