UNPKG

reka-ui

Version:

Vue port for Radix UI Primitives.

67 lines (59 loc) 1.59 kB
import type { Component, PropType } from 'vue' import { defineComponent, h } from 'vue' import { Slot } from './Slot' export type AsTag = | 'a' | 'button' | 'div' | 'form' | 'h2' | 'h3' | 'img' | 'input' | 'label' | 'li' | 'nav' | 'ol' | 'p' | 'span' | 'svg' | 'ul' | 'template' | ({} & string) // any other string export interface PrimitiveProps { /** * Change the default rendered element for the one passed as a child, merging their props and behavior. * * Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. */ asChild?: boolean /** * The element or component this component should render as. Can be overwritten by `asChild`. * @defaultValue "div" */ as?: AsTag | Component } // For self closing tags, don't provide default slots because of hydration issue const SELF_CLOSING_TAGS = ['area', 'img', 'input'] export const Primitive = defineComponent({ name: 'Primitive', inheritAttrs: false, props: { asChild: { type: Boolean, default: false, }, as: { type: [String, Object] as PropType<AsTag | Component>, default: 'div', }, }, setup(props, { attrs, slots }) { const asTag = props.asChild ? 'template' : props.as if (typeof asTag === 'string' && SELF_CLOSING_TAGS.includes(asTag)) return () => h(asTag, attrs) if (asTag !== 'template') return () => h(props.as, attrs, { default: slots.default }) return () => h(Slot, attrs, { default: slots.default }) }, })