import { computed, useAttrs } from 'vue' /** * Composable that merges HTML attributes from attrs with prop defaults * Prioritizes attrs over props, allowing HTML attributes to be passed directly * @param props - Component props object with defaults * @returns Computed object with merged attribute values */ export function useAttrsWithDefaults>(props: T) { const attrs = useAttrs() return { // Common boolean attributes disabled: computed( () => (attrs.disabled as boolean | undefined) ?? (props.disabled as boolean | undefined) ?? false, ), required: computed( () => (attrs.required as boolean | undefined) ?? (props.required as boolean | undefined) ?? false, ), // Common string attributes id: computed(() => (attrs.id as string | undefined) ?? (props.id as string | undefined)), name: computed(() => (attrs.name as string | undefined) ?? (props.name as string | undefined)), type: computed(() => (attrs.type as string | undefined) ?? (props.type as string | undefined)), href: computed(() => (attrs.href as string | undefined) ?? (props.href as string | undefined)), target: computed(() => (attrs.target as string | undefined) ?? (props.target as string | undefined)), rel: computed(() => (attrs.rel as string | undefined) ?? (props.rel as string | undefined)), download: computed(() => (attrs.download as string | undefined) ?? (props.download as string | undefined)), placeholder: computed(() => (attrs.placeholder as string | undefined) ?? (props.placeholder as string | undefined)), // Common number attributes rows: computed(() => (attrs.rows as number | undefined) ?? (props.rows as number | undefined)), maxlength: computed(() => (attrs.maxlength as number | undefined) ?? (props.maxlength as number | undefined)), // Raw attrs for spreading attrs, } }