diff --git a/src/index.tsx b/src/index.tsx index a14ef6b..89fd848 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -196,7 +196,12 @@ function makeComponent(baseName: string, rootDef: TagDef, rootProps: Record{children} + const finalProps = { class: classNames.join(' '), ...baseAttrs, ...props } + + if (partName && def.render) + return def.render({ props: finalProps, children }) + + return {children} } } @@ -315,4 +320,4 @@ function tagName(base: string): string { } // shortcut so you only have to import one thing, if you want -define.Styles = Styles \ No newline at end of file +define.Styles = Styles diff --git a/src/tests/index.test.tsx b/src/tests/index.test.tsx index 808691b..c0547bd 100644 --- a/src/tests/index.test.tsx +++ b/src/tests/index.test.tsx @@ -558,6 +558,82 @@ describe('custom render function', () => { expect(html).toContain(' { + const Component = define('PartRender', { + parts: { + Icon: { + base: 'span', + color: 'blue', + render: ({ props, children }) => ( + ★ {children} + ) + } + }, + render: ({ props, parts }) => ( + + star + + ) + }) + + const html = renderToString(Component({})) + expect(html).toContain('★ star') + expect(html).toContain('class="PartRender_Icon"') + }) + + test('part render receives computed class and props', () => { + let receivedProps: any + + const Component = define('PartRenderProps', { + parts: { + Item: { + base: 'li', + render: ({ props, children }) => { + receivedProps = props + return
  • {children}
  • + } + } + }, + render: ({ props, parts }) => ( + + item + + ) + }) + + renderToString(Component({})) + expect(receivedProps.class).toBe('PartRenderProps_Item') + expect(receivedProps['data-test']).toBe('value') + }) + + test('part render works with variants', () => { + const Component = define('PartRenderVariant', { + variants: { + size: { + small: { fontSize: 12 }, + large: { fontSize: 24 } + } + }, + parts: { + Label: { + fontWeight: 'bold', + render: ({ props, children }) => ( + Label: {children} + ) + } + }, + render: ({ props, parts }) => ( + + text + + ) + }) + + const html = renderToString(Component({ size: 'large' })) + expect(html).toContain('Label: text') + expect(html).toContain('PartRenderVariant_Label') + }) }) describe('Styles component', () => {