Skip to content

Conversation

@bsunderhus
Copy link
Contributor

@bsunderhus bsunderhus commented Mar 10, 2023

Summary

Slot children render function is a complex API that is not properly supported. #27089

To support this, this RFC proposes to create a custom JSX pragma to ensure slot declaration will not lose any property
and will be capable of properly rendering with children render function.

RFC

Current issues

Slot children render function won't override existing children. #27089

Repro: https://codesandbox.io/s/elated-babbage-46ez1w?file=/example.tsx

It's not possible to use children render function to override an entire slot, if children are already used. The above is a minimal repro of an issue that can be seen in Fluent in the AccordionHeader component. The component renders the button slot which contains its own children. JSX children will win over props children - which is how children render functions are rendered by getSlots

const { slots, slotProps } = getSlots<AccordionHeaderSlots>(state);
return (
<AccordionHeaderContext.Provider value={contextValues.accordionHeader}>
<slots.root {...slotProps.root}>
<slots.button {...slotProps.button}>
{state.expandIconPosition === 'start' && <slots.expandIcon {...slotProps.expandIcon} />}
{slots.icon && <slots.icon {...slotProps.icon} />}
{slotProps.root.children}
{state.expandIconPosition === 'end' && <slots.expandIcon {...slotProps.expandIcon} />}
</slots.button>
</slots.root>
</AccordionHeaderContext.Provider>

Requirements for children render function:

  • should be able to override the entire slot
  • When rendering the original children, should respect nested slots.

@bsunderhus bsunderhus added the Type: RFC Request for Feedback label Mar 10, 2023
@bsunderhus bsunderhus requested a review from a team as a code owner March 10, 2023 14:48
@bsunderhus bsunderhus self-assigned this Mar 10, 2023
@github-actions github-actions bot added this to the March Project Cycle Q1 2023 milestone Mar 10, 2023
@fabricteam
Copy link
Collaborator

fabricteam commented Mar 10, 2023

📊 Bundle size report

🤖 This report was generated against 4f76849de438f2ee7842121ac3b8176ba1c0a2a5

@codesandbox-ci
Copy link

codesandbox-ci bot commented Mar 10, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 7fc2f47:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration
modest-goldberg-ltb7b8 PR

@size-auditor
Copy link

size-auditor bot commented Mar 10, 2023

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 4f76849de438f2ee7842121ac3b8176ba1c0a2a5 (build)

@bsunderhus bsunderhus requested review from a team March 13, 2023 12:45
@layershifter
Copy link
Member

Based on a discussion yesterday: the approach with slot() function will be a breaking change for consumers that use composition and rely on custom render templates that are using getSlots().

@layershifter
Copy link
Member

layershifter commented Mar 16, 2023

@bsunderhus I prototyped a less breaking change that allows us to keep existing code or to do gradual changes: https://codesandbox.io/s/wispy-leftpad-f8yi37?file=/example.tsx.

Key changes compared to current implementation:

  • resolveShorthand stores defaultProps.children, it's a single thing that we need to store to make it working
  • getSlots() does not handle typeof children === 'function', it will be handled by JSX pragma
  • JSX pragma is a thin wrapper that handles a case with function

That solution passing cases in this example. Key benefit is that we don't change other internals and don't need to apply changes to other hooks. The next step could be moving functionality of getSlots() to JSX pragma.

@bsunderhus
Copy link
Contributor Author

bsunderhus commented Mar 16, 2023

@bsunderhus I prototyped a less breaking change that allows us to keep existing code or to do gradual changes: https://codesandbox.io/s/wispy-leftpad-f8yi37?file=/example.tsx.

Key changes compared to current implementation:

  • resolveShorthand stores defaultProps.children, it's a single thing that we need to store to make it working
  • getSlots() does not handle typeof children === 'function', it will be handled by JSX pragma
  • JSX pragma is a thin wrapper that handles a case with function

That solution passing cases in this example. Key benefit is that we don't change other internals and don't need to apply changes to other hooks. The next step could be moving functionality of getSlots() to JSX pragma.

I'll see to add it as an option on the RFC! Thx for the contribution @layershifter!

@ling1726
Copy link
Contributor

Based on a discussion yesterday: the approach with slot() function will be a breaking change for consumers that use composition and rely on custom render templates that are using getSlots().

Honestly, why do we have _unstable suffix if we're not allowed to change internals signature for cases that would clearly improve internals?

@layershifter @bsunderhus let's ask WISE (a.k.a @jspurlin) for their thoughts on this, they are a partner that have fully invested in composition

@bsunderhus bsunderhus force-pushed the rfx/slot-children-render-function branch 2 times, most recently from ba8cbf7 to ae02eee Compare March 17, 2023 12:09
@layershifter
Copy link
Member

@bsunderhus As RFC is quite big, would you mind to run doctoc to generate table of contents in it? 🙏

@bsunderhus bsunderhus force-pushed the rfx/slot-children-render-function branch from 09920aa to bf41470 Compare March 22, 2023 13:01
@Hotell Hotell requested a review from marcosmoura March 23, 2023 13:06
@bsunderhus bsunderhus requested review from behowell and khmakoto March 23, 2023 20:04
@bsunderhus bsunderhus reopened this Mar 29, 2023
@bsunderhus bsunderhus requested a review from a team March 29, 2023 17:31
bsunderhus and others added 19 commits March 29, 2023 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: RFC Request for Feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants