figma / code-connect

A tool for connecting your design system components in code with your design system in Figma
MIT License
981 stars 70 forks source link

[HTML] Make API a bit more flexible #175

Open massi08 opened 2 months ago

massi08 commented 2 months ago

On our design system we have one particular component which is exposed in the library in multiple components. This particular component has 10 variants, so i have to use figma.connect() 10 times. To avoid repeating code multiple times because the only thing that changes in the code is that we add change only one property.

So for the 10 code.connect calls the only thing that changes is that we add in props object variant: figma.string(variant) and we also

<component variant="${props.accent}" ...multiple other props>
  ${props.label}
</component>

Instead of repeating code for each code.connect like this

figma.connect(
  "URL",
  {
    props: sharedProps,
    example: (props) => html`
      <component variant="red" ...moreProps>
        ${props.label}
      </component>
    `
  }
);

figma.connect(
  "URL",
  {
    props: sharedProps,
    example: (props) => html`
      <component variant="blue" ...moreProps>
        ${props.label}
      </component>
    `
  }
);

ATTEMPT 1

So I tried separating the config in a separate function like this but i get an error:

const config = (accent) => ({
  props: {
    // shared props
    ...sharedProps,
    accent: figma.string(accent), // or other variant
  },
  example: (props) => html`
    <component variant="${props.accent}" ...moreProps>
      ${props.label}
    </component>
  `
})

figma.connect(
  "URL",
  config('blue')
);

figma.connect(
  "URL2",
  config('red')
);

Error:

undefined: The second argument to figma.connect() must be an object literal. Example usage:
`figma.connect('https://www.figma.com/file/123?node-id=1-1', {
  example: () => html`<button />`
})`

ATTEMPT 2 I tried instead of calling `config(accent)' this:

figma.connect(
  "URL2",
  {...config('blue')}
);

i get this error

undefined: TypeError: Cannot read properties of undefined (reading 'initializer')

For a better DX i think the API should be a little more flexible and allow passing something else than object litterals especially for such cases where the same code is repeated a lot of times.

tomduncalf-figma commented 2 months ago

Hey @massi08, thanks for the report. Just to validate my understanding, these are multiple different components (not variants) in Figma, so each has a different URL, but the code version is identical save for one prop which changes?

If so then we don't have a great solution for avoiding repetition right now. The reason you're hitting issues is that Code Connect files are actually parsed rather than executed, so we only support a subset of JS syntax.

One option is that you could have a script which generates the Code Connect file for each of these from one master copy, a bit like the example script we have for linking icons.

I'm going to raise this with the team for discussion about how we could better support your use case or more JS syntax.

massi08 commented 2 months ago

Yes for exemple, tag component which is basically the same except it has different colors. To make it easier for designers when using our library to spot the right tag, instead of exposing one tag component with the accent property. We expose each variant in a component for e.g tag red, tag blue... But on the developer end we only expose one tag component with a variant property.

Thanks for your reply, I will check the script. I now understand why I am facing so many restrictions. for e.g: No ternaries in the string interpolation, the ones above.

I guess you have your reasons to only parse and not execute these files maybe for security or performance. But we will certainly appreciate more flexibility.