The issue you're experiencing is due to how Vue handles attribute inheritance and class merging when using $attrs and inheritAttrs: false. When you pass a class (like bg-black) to a component, Vue normally merges it onto the root element of the component. However, when you use inheritAttrs: false and manually bind $attrs to a nested element, Vue does not automatically merge the class attribute; instead, it passes it as a plain attribute, which can break how Tailwind (and CSS in general) applies styles.
In your example:
// FooComponent.vue
<template>
<div>
<div v-bind="$attrs">
<slot />
</div>
</div>
</template>
<script lang="ts" setup>
defineOptions({ inheritAttrs: false });
</script>
When you use:
<FooComponent class="bg-black">Foo Component</FooComponent>
The class="bg-black" is passed via $attrs, but since it's not merged with the nested div's class, it doesn't get applied as a class—it's just an attribute, so Tailwind's styles don't take effect.
Solution:
You need to explicitly merge the class from $attrs with any existing classes on the nested div. For example:
<template>
<div>
<div :class="$attrs.class">
<slot />
</div>
</div>
</template>
Or, if you want to bind all other attributes as well:
<template>
<div>
<div v-bind="Object.assign({}, $attrs, { class: $attrs.class })">
<slot />
</div>
</div>
</template>
Alternatively, you can use the spread operator and merge classes properly.