code-connect icon indicating copy to clipboard operation
code-connect copied to clipboard

Can we get an option to remove a React Fragment from Code Connect?

Open Meloyski opened this issue 1 year ago • 4 comments

We use Nested Components within our Design Kit. Most of the time, this component serves a purpose of just functionality and isn't necessarily the actual parent of the children.

For Example, in Figma we have:

  • BaseComponent
    • StartContent
    • EndContent

MainComponent

  • MainComponent
    • BaseComponent
      • ...

What it looks like in our React Library is:

<MainComponent>
  <StartContent />
  <EndContent />
</MainComponent>

We've added Code Connect to our BaseCompoent and since it thinks we are wanting to add a React component, we just add a React.fragment. StartContent and EndContent already have Code Connect setup, so the 'Something' is placeholder to satisfy the Figma typescript. We are using an empty 'imports'.

BaseComponent (Code Connect):

import { Something } from '@library';
import figma from '@figma/code-connect';

figma.connect(
 Something,
 'Link to Figma Component',
 {
   imports: [''],
   props: {
      children: figma.children('*'),
   },
   example: ({ children }) => <>{children}</>,
 },
);

BaseComponent in Code Connect Example:

<>
  <StartContent />
  <EndContent />
</>

MainComponent (Code Connect):

import { MainComponent } from '@library';
import figma from '@figma/code-connect';

figma.connect(
 MainComponent,
 'Link to Figma Component',
 {
   props: {
      children: figma.children('*'),
   },
   example: ({ children }) => <MainComponent>{children}</MainComponent>,
 },
);

MainComponent in Code Connect Example:

<MainComponent>
  <>
    <StartContent />
    <EndContent />
  </>
</MainComponent>

It's not a huge deal tbh, it just cleaner without the React.Fragments. There's some examples where we have a lot of nested components, so the examples have 3-4 React Fragments.

Not sure of a solution, but just wanted to bring this topic up to see if any other teams have had this and/or if there's a solution that I might be missing.

Regardless, our team has been loving what we've implemented so far with Code Connect. Excited to be able to provide our team with it. Thanks for this feature, it has been huge for us <3

Meloyski avatar Aug 15 '24 16:08 Meloyski

Thanks for the comment @Meloyski ! This is an interesting use case, we're thinking on ways to improve nested components, and maybe be a bit more smart on how we display them. Don't have more specifics at the moment but will update when we have more news.

ptomas-figma avatar Aug 15 '24 16:08 ptomas-figma

+1 to wanting this, we have a situation with our menu component where the divider is just a prop in Figma, but actually adds an additional component in code, so need to wrap in a fragment. Screenshot 2024-08-23 at 8 37 50 AM

alisonjoseph avatar Aug 23 '24 13:08 alisonjoseph

We also have something like this. Though in our case, we have an intermediary subcomponent, which isn't ideal, but it is what it is.

So in Figma node land, we have:

  • Main Tabs component
    • Tab group component, which is a composition of 1-10 individual Tab components 🤮
      • Tab component
      • Tab component
      • Tab component
      • etc

Since we have the individual Tab component hooked up, we don't really care about the Tab group component, since we should be able to render the appropriate amount of Tab components inside the parent Tabs component, but we can't get this working without a fragment.

I expected to be able to skip a level with my props like so:

{
    props: {
      ...otherProps,
      children: figma.nestedProps('⚙️ Tab group', {
        tabs: figma.children(["⚙️ Natural width tab"]),
      }),
    },
    example: ({ ...otherProps, children }) => (
      <Tabs {...otherProps}>
        {children.tabs}
      </Tabs>
    );
  }

but that doesn't work, since nestedProps always selects a single instance.

Our only other option is to do something like @Meloyski is doing, and have ⚙️ Tab group return a fragment with children, but then our connected code looks unrealistically wonky like:

<Tabs>
  <>
    <Tab name="Tab label">{"CONTENT_HERE"}</Tab>
    <Tab name="Tab label">{"CONTENT_HERE"}</Tab>
    <Tab name="Tab label">{"CONTENT_HERE"}</Tab>
    ...
  </>
</Tabs>

I wish there was a way we could just skip level the children, or remove the fragment.

ericandrewscott avatar Sep 05 '24 10:09 ericandrewscott

Any updates on this? Also needing it in my context.

Whenever I have a component with a "default variant" and another variant that uses "instance swap," I'm trying to pull just the content of the component as children and put the encapsulating tag in the example template itself. However, I have to encapsulate the children with the React Fragment <> for them to display their contents, and I don't want those fragments to show in Code Connect.

Example

Publish the 'default footer' of a modal component that will be used as a child of the main Modal:

figma.connect(BcModal, '<FIGMA_MODAL_FOOTER>', {
  props: {
    children: figma.children(['Button']),
  },

  example: ({ children }) => <>{children}</>,
})

In the Modal component itself, pull the children by layer name Modal Footer that can either be the variant above OR it could be an instance swapped component; display the contents inside a wrapping <BcModal.Footer> tag:

figma.connect(BcModal, '<FIGMA_MODAL>', {
  props: {
    ...
    footer: figma.children('Modal Footer'),
    ...
  },
  example: ({ ..., body, footer, ... }) => (
    <BcModal ...>
      ...
      <BcModal.Body>{body}</BcModal.Body>
      <BcModal.Footer>{footer}</BcModal.Footer>
    </BcModal>
  ),
})

What I get today inside Code Connect is either:

Default (known) variant Instance swap (unknown)
Image Image

I'd like to not see the React Fragments there 🙏

renandf avatar Feb 26 '25 04:02 renandf