UNPKG

reka-ui

Version:

Vue port for Radix UI Primitives.

62 lines (55 loc) 2.1 kB
import type { ComponentOptionsBase, DefineComponent, VNodeProps } from 'vue' import type { ComponentProps } from 'vue-component-type-helpers' import { h, mergeProps } from 'vue' import { useForwardExpose } from './useForwardExpose' // TODO: TEST // From vue next // https://github.com/vuejs/core/blob/1f2a652a9d2e3bec472fb1786a4c16d6ccfa1fb1/packages/runtime-core/src/h.ts#L53-L58 type RawProps = VNodeProps & { // used to differ from a single VNode object as children __v_isVNode?: never // used to differ from Array children [Symbol.iterator]?: never } & Record<string, any> // types inspired from vue-test-utils // https://github.com/vuejs/test-utils/blob/main/src/mount.ts#L36 interface MountingOptions<Props> { /** * Default props for the component */ props?: (RawProps & Props) | ({} extends Props ? null : never) | ((attrs: Record<string, any>) => (RawProps & Props)) /** * Pass attributes into the component */ attrs?: Record<string, unknown> } export function withDefault< T, C = T extends ((...args: any) => any) | (new (...args: any) => any) ? T : T extends { props?: infer Props } ? DefineComponent< Props extends Readonly<(infer PropNames)[]> | (infer PropNames)[] ? { [key in PropNames extends string ? PropNames : string]?: any } : Props > : DefineComponent, P extends ComponentProps<C> = ComponentProps<C>, >( originalComponent: T, options?: MountingOptions<P>, ): T export function withDefault<T extends ComponentOptionsBase<{}, {}, {}, any, any, any, any, any>>(WrappedComponent: T, options?: MountingOptions<any>) { return ({ inheritAttrs: false, name: `${WrappedComponent.__name ?? ''}Wrapper`, setup(_, ctx) { return () => { const optionProps = typeof options?.props === 'function' ? options?.props(ctx.attrs) : options?.props const { forwardRef } = useForwardExpose() const mergedProps = mergeProps(optionProps, ctx.attrs) return h(WrappedComponent, { ...mergedProps, ref: forwardRef }, ctx.slots) } }, }) as T }