Skip to content

Expose Reka UI useForward* utilities #6368

@reinsp5

Description

@reinsp5

Package

v4.x

Description

Please consider exposing Reka UI's useForward* utilities ( such as useForwardProps and useForwardPropsAndEmits ).

When creating reusable components by wrapping multiple NuxtUI components, it feels inefficient to either implement custom logic to bypass Vue 3's BooleanCasting or add reka-ui as a direct dependency just to access these specific functions.

Example:

<script lang="ts" setup>
import type { FormFieldProps, SelectProps } from "@nuxt/ui";
type MySelectProps = FormFieldProps & SelectProps;

const props = defineProps<MySelectProps>()
const forwarded = useForwardProps(props)
</script>

<template>
  <UFormField v-bind="forwarded">
    <USelect v-bind="{...forwarded, ...$attrs}" />
  </UFormField>
</template>

Note: In practice, you may need to resolve conflicting props, but we'll ignore that for now.

Additional context

Example Scenario:

Suppose I want to create a composite component, , which combines and to provide both form validation and selection logic in one place.

My primary reason for using in this wrapper is to leverage its UI features—such as labels, hints, and description slots—rather than just validation logic.

By wrapping these into a single MySelect component, I can ensure a consistent UI/UX across the application. However, this architectural choice makes the "Boolean Casting" issue even more prominent, as I need to pass through all the functional props of the inner input component while maintaining the layout props of the FormField.

<MySelect :items="items" orientation="vertical" v-model="value" />

The Problem:

While users expect the component to work as shown above, Vue 3’s Boolean Casting behavior causes issues. Because the open prop (and other boolean props) isn't explicitly passed to MySelect, it is implicitly set to false. This prevents the internal from managing its own state correctly, often breaking the component's default behavior.

Current Workarounds:
To avoid this, we are currently forced to:

  1. Manually set open to undefined within MySelect.

  2. Or, manually manage the open state inside the wrapper component.

These approaches are far from ideal. It would be much more efficient if we could create transparent wrappers with minimal boilerplate, allowing us to leverage NuxtUI’s built-in state management (like how USelect self-manages its open state) without redundant code.

Developer Experience (DX):
Furthermore, handling multiple boolean props—some defaulting to true and others to false—is quite cumbersome. Having to constantly worry about Boolean Casting overriding true defaults is a significant mental burden that could be easily solved by exposing Reka UI’s utilities.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesttriageAwaiting initial review and prioritizationv4#4488

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions