First piece of the reka-ui removal: a small asChild/Slot implementation to replace reka-ui's Primitive component.
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { h } from 'vue'
|
|
import { mount } from '@vue/test-utils'
|
|
import { Primitive } from '../src/lib/primitive'
|
|
|
|
describe('Primitive', () => {
|
|
it('renders the "as" tag with forwarded attrs when asChild is false', () => {
|
|
const wrapper = mount(Primitive, {
|
|
props: { as: 'a' },
|
|
attrs: { href: '/somewhere', class: 'link' },
|
|
slots: { default: () => 'Go' },
|
|
})
|
|
const el = wrapper.get('a')
|
|
expect(el.attributes('href')).toBe('/somewhere')
|
|
expect(el.classes()).toContain('link')
|
|
expect(el.text()).toBe('Go')
|
|
})
|
|
|
|
it('clones the single child and merges attrs onto it when asChild is true', async () => {
|
|
let clicked = false
|
|
const wrapper = mount(Primitive, {
|
|
props: { asChild: true },
|
|
attrs: { class: 'from-parent', 'data-slot': 'button', onClick: () => { clicked = true } },
|
|
slots: {
|
|
default: () => h('button', { class: 'from-child', type: 'button' }, 'Click'),
|
|
},
|
|
})
|
|
const el = wrapper.get('button')
|
|
expect(el.attributes('data-slot')).toBe('button')
|
|
expect(el.attributes('type')).toBe('button')
|
|
expect(el.classes()).toContain('from-parent')
|
|
expect(el.classes()).toContain('from-child')
|
|
await el.trigger('click')
|
|
expect(clicked).toBe(true)
|
|
})
|
|
|
|
it('throws if asChild is true with zero or multiple children', () => {
|
|
expect(() =>
|
|
mount(Primitive, {
|
|
props: { asChild: true },
|
|
slots: { default: () => [h('span', 'a'), h('span', 'b')] },
|
|
}),
|
|
).toThrow()
|
|
})
|
|
})
|