From 9b6e1e91ec77d7e03589cac256d97fb9cd942184 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Sat, 24 Jan 2026 09:47:22 -0800 Subject: [PATCH] parts can have a custom render() --- src/index.tsx | 8 +++-- src/tests/index.test.tsx | 76 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index a14ef6b..d1ea08a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -196,7 +196,11 @@ function makeComponent(baseName: string, rootDef: TagDef, rootProps: Record{children} + const finalProps = { class: classNames.join(' '), ...baseAttrs, ...props, children } + + const content = (partName && def.render) ? def.render(finalProps) : children + + return {content} } } @@ -315,4 +319,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..c1f3a03 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) => <>★ {props.children} + } + }, + render: ({ props, parts }) => ( + + star + + ) + }) + + const html = renderToString(Component({})) + expect(html).toContain('★ star') + expect(html).toContain('class="PartRender_Icon"') + expect(html).toContain(' { + let receivedProps: any + + const Component = define('PartRenderProps', { + parts: { + Item: { + base: 'li', + render: (props) => { + receivedProps = props + return <>item: {props.children} + } + } + }, + render: ({ props, parts }) => ( + + content + + ) + }) + + const html = renderToString(Component({})) + expect(receivedProps.class).toBe('PartRenderProps_Item') + expect(receivedProps['data-test']).toBe('value') + expect(receivedProps.children).toBe('content') + expect(html).toContain(' { + const Component = define('PartRenderVariant', { + variants: { + size: { + small: { fontSize: 12 }, + large: { fontSize: 24 } + } + }, + parts: { + Label: { + fontWeight: 'bold', + render: (props) => <>Label: {props.children} + } + }, + render: ({ props, parts }) => ( + + text + + ) + }) + + const html = renderToString(Component({ size: 'large' })) + expect(html).toContain('Label: text') + expect(html).toContain('PartRenderVariant_Label') + }) }) describe('Styles component', () => {