Dynamic Props â
Inspired from Vuetify, anu provides a way to configure the component props dynamically.
Why Dynamic Props? â
When you use a component from component libraries, that component has props defaults assigned to it according to common needs. For example, color
prop is always set to primary
because it is the most common color used in the application.
However, what about not so obvious props like size
prop. Your design system might requires smaller components than provided by the component library. In that case you have to write size
prop everywhere.
<template>
<ABtn size="sm">Submit</ABtn>
<ABtn size="sm">Preview</ABtn>
<ABtn size="sm">Download</ABtn>
</template>
You have to repeat size
prop everywhere which is super inconvenient and has few downsides as well (we aren't going to discuss them here).
The Solution? â
But what if we have a way to configure the props defaults for all the components provided by component libraries? That would be super convenient and we don't have to repeat the same props everywhere.
With anu, you can configure the props defaults for all the components while registering the plugin.
// âšī¸ Anu don't have `size` prop. This is just an example.
createApp(App)
.use(anu, {
propsDefaults: {
ABtn: {
size: 'sm',
},
}
})
Now, You can write your components without repeating the size
prop and keep your code DRY.
<template>
<ABtn>Submit</ABtn>
<ABtn>Preview</ABtn>
<ABtn>Download</ABtn>
</template>
Using propsDefaults
you can set props defaults for any Anu component.
Nested Props Defaults â
Life is not always simple and your client might need visually different component based on context. For example, you might need a text variant button inside alert and normal (fill variant) button elsewhere. Then we are back to square one. We have to repeat the variant
prop in every alert
<template>
<AAlert>
<p>You're running out of storage!</p>
<ABtn variant="text" class="ms-auto">Upgrade</ABtn>
</AAlert>
<AAlert>
<p>Critical error occurred!</p>
<ABtn variant="text" class="ms-auto">Check</ABtn>
</AAlert>
<AAlert>
<p>Payment failed!</p>
<ABtn variant="text" class="ms-auto">Retry</ABtn>
</AAlert>
</template>
Anu also provides support for nested props defaults. You can set props defaults for a component inside another component.
createApp(App)
.use(anu, {
propsDefaults: {
AAlert: {
ABtn: {
variant: 'text',
},
},
}
})
Now, with new props defaults, you can write your components without repeating the variant
prop and keep your code DRY.
<template>
<AAlert>
<p>You're running out of storage!</p>
<ABtn class="ms-auto">Upgrade</ABtn>
</AAlert>
<AAlert>
<p>Critical error occurred!</p>
<ABtn class="ms-auto">Check</ABtn>
</AAlert>
<AAlert>
<p>Payment failed!</p>
<ABtn class="ms-auto">Retry</ABtn>
</AAlert>
</template>
Cool right?
Hold on, there is more. We're still repeating the class
attribute.
Class, Style & Attrs Defaults â
Apart from props, Anu also supports setting defaults for class
, style
and attrs
for all the components.
createApp(App)
.use(anu, {
propsDefaults: {
AAlert: {
ABtn: {
variant: 'text',
class: 'ms-auto',
// style: {}, /* You can also set default styles */
// attrs: {}, /* Set default attrs, Just in case if needed */
},
},
},
})
Finally, we have a way to write our components without repeating the code and keep our code DRY.
<template>
<!-- All buttons will have "ms-auto" class "light" variant -->
<AAlert>
<p>You're running out of storage!</p>
<ABtn>Upgrade</ABtn>
</AAlert>
<AAlert>
<p>Critical error occurred!</p>
<ABtn>Check</ABtn>
</AAlert>
<AAlert>
<p>Payment failed!</p>
<ABtn>Retry</ABtn>
</AAlert>
</template>
Defaults for your component â
You can also set defaults for your own components. For example, you can set defaults for your custom AppBtn
component.
createApp(App)
.use(anu, {
propsDefaults: {
AppBtn: {
class: 'uppercase',
},
AppAAlert: {
AppBtn: {
propName: false,
},
}
},
})
Later in your component use useDefaults
composable:
<script lang="ts" setup>
// other imports
import { useDefaults } from 'anu-vue'
// â Make sure to use `_props` as name
const _props = defineProps<{}>() // or `withDefaults`
const { props, defaultsClass, defaultsStyle, defaultsAttrs } = useDefaults(_props)
// other code
</script>
<template>
<div
class="my-class"
:class="defaultsClass"
:style="[
{ color: 'red' },
defaultsStyle,
]"
v-bind="defaultsAttrs"
>
<!-- Your component content -->
<!-- â If you want to access props use `props.propName` -->
</div>
</template>
Whoa! Anu also added DX magic to your custom components
WARNING
When you use useDefaults
composable, you have to use props.propName
while accessing the props to get props configured by defaults.
Even in your template, use props.propName
to access the props.