parts can have a custom render()
This commit is contained in:
parent
e772e0e711
commit
9b6e1e91ec
|
|
@ -196,7 +196,11 @@ function makeComponent(baseName: string, rootDef: TagDef, rootProps: Record<stri
|
|||
classNames.push(variantKey === true ? variantName : `${variantName}-${variantKey}`)
|
||||
}
|
||||
|
||||
return <Tag class={classNames.join(' ')} {...baseAttrs} {...props}>{children}</Tag>
|
||||
const finalProps = { class: classNames.join(' '), ...baseAttrs, ...props, children }
|
||||
|
||||
const content = (partName && def.render) ? def.render(finalProps) : children
|
||||
|
||||
return <Tag {...finalProps}>{content}</Tag>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,4 +319,4 @@ function tagName(base: string): string {
|
|||
}
|
||||
|
||||
// shortcut so you only have to import one thing, if you want
|
||||
define.Styles = Styles
|
||||
define.Styles = Styles
|
||||
|
|
|
|||
|
|
@ -558,6 +558,82 @@ describe('custom render function', () => {
|
|||
expect(html).toContain('<footer')
|
||||
expect(html).toContain('Main Content')
|
||||
})
|
||||
|
||||
test('part can have its own render function', () => {
|
||||
const Component = define('PartRender', {
|
||||
parts: {
|
||||
Icon: {
|
||||
base: 'span',
|
||||
color: 'blue',
|
||||
render: (props) => <>★ {props.children}</>
|
||||
}
|
||||
},
|
||||
render: ({ props, parts }) => (
|
||||
<parts.Root>
|
||||
<parts.Icon>star</parts.Icon>
|
||||
</parts.Root>
|
||||
)
|
||||
})
|
||||
|
||||
const html = renderToString(Component({}))
|
||||
expect(html).toContain('★ star')
|
||||
expect(html).toContain('class="PartRender_Icon"')
|
||||
expect(html).toContain('<span') // base tag is preserved
|
||||
})
|
||||
|
||||
test('part render receives props including children', () => {
|
||||
let receivedProps: any
|
||||
|
||||
const Component = define('PartRenderProps', {
|
||||
parts: {
|
||||
Item: {
|
||||
base: 'li',
|
||||
render: (props) => {
|
||||
receivedProps = props
|
||||
return <>item: {props.children}</>
|
||||
}
|
||||
}
|
||||
},
|
||||
render: ({ props, parts }) => (
|
||||
<parts.Root>
|
||||
<parts.Item data-test="value">content</parts.Item>
|
||||
</parts.Root>
|
||||
)
|
||||
})
|
||||
|
||||
const html = renderToString(Component({}))
|
||||
expect(receivedProps.class).toBe('PartRenderProps_Item')
|
||||
expect(receivedProps['data-test']).toBe('value')
|
||||
expect(receivedProps.children).toBe('content')
|
||||
expect(html).toContain('<li') // base tag preserved
|
||||
expect(html).toContain('item: content')
|
||||
})
|
||||
|
||||
test('part render works with variants', () => {
|
||||
const Component = define('PartRenderVariant', {
|
||||
variants: {
|
||||
size: {
|
||||
small: { fontSize: 12 },
|
||||
large: { fontSize: 24 }
|
||||
}
|
||||
},
|
||||
parts: {
|
||||
Label: {
|
||||
fontWeight: 'bold',
|
||||
render: (props) => <>Label: {props.children}</>
|
||||
}
|
||||
},
|
||||
render: ({ props, parts }) => (
|
||||
<parts.Root>
|
||||
<parts.Label>text</parts.Label>
|
||||
</parts.Root>
|
||||
)
|
||||
})
|
||||
|
||||
const html = renderToString(Component({ size: 'large' }))
|
||||
expect(html).toContain('Label: text')
|
||||
expect(html).toContain('PartRenderVariant_Label')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Styles component', () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user