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

React children composition

Open ericandrewscott opened this issue 1 year ago • 1 comments

I'm using 1.2.4.

It's not clear how to compose children into an array of objects and provide that to the parent, or to use Typescript to hoist props to the parent.

I'm working on a Step Indicator component, seen below. Screenshot 2024-12-12 at 6 57 11 AM

The parent code for the component is like so:

      <StepIndicator
        stepIndicatorSize={stepIndicatorSize}
        activeStep={2} // set actual active step as a number
        labelSize="medium" // set actual label size, "small" | "medium" | "large"
        // convert to array of objects, like steps={[{label: 'Step 1'}, {label: 'Step 2'}]}
        steps={children}
      />

So I've added comments to help for some props that are unavailable on the parent, but the steps prop is the one I'm really trying to solve.

Below is the subcomponent for the horizontal single steps. Screenshot 2024-12-12 at 8 22 13 AM

And here is the code we've hooked up to that subcomponent:

// Contextual horizontal small subcomponent
figma.connect(
  StepIndicator,
  "https://www.figma.com/design/cwklAvgWpiUVb8cKdhbR1U/Step-Indicator-%5BALPHA%5D?node-id=1140-38832",
  {
    props: {
      label: figma.nestedProps('_ / Step indicator / Label / Text only', {
        text: figma.textContent('✏️ Label'),
      }),
    },
    example: (props) => <>label: {props.label.text} </>,
  },
);

So this emits: <>label: Label </> for each step, but we'd like it to emit { label: "Label }...

  • without the <> React fragment
  • in curlies
  • with the value of the label in ""

Is that even possible? So currently, the output for the whole thing is:

<StepIndicator activeStep={2} // set actual active step as a number
 labelSize="medium" // set actual label size, "small" | "medium" | "large"
 
// convert to array of objects, like steps={[{label: 'Step 1'}, {label: 'Step 2'}]}
steps=<>label: Label </><>label: Label </><>label: Label </>/>

But we'd like it to be:

<StepIndicator
    activeStep={2} // set actual active step as a number
    labelSize="medium" // set actual label size, "small" | "medium" | "large"
    steps={[
        { label: "Label" },
        { label: "Label" },
        { label: "Label" },

Is that possible?

Additionally, if we could:

  • Look into the children and see which on is the Current variant to return the activeStep to the parent
  • Look at the Label size prop on the first child to return the value to the labelSize prop on the parent

Totally opening to writing this in a more efficient/different way!

ericandrewscott avatar Dec 12 '24 15:12 ericandrewscott

Hey @ericandrewscott, thanks for the question!

We don't have anything in the API to allow you to dynamically execute code to create some output, so as you explored already the way to do this today would be to return some JSX and allow code connect to map the children.

We're exploring APIs that'll let you do more freeform transformations like this - will keep you posted if we decide to move forward with these.

slees-figma avatar Dec 16 '24 11:12 slees-figma