figma / code-connect

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

Feature request: add ability to concat string props within example snippet #80

Open glomotion opened 4 months ago

glomotion commented 4 months ago

Describe the feature you'd like: We have a Button component in figma, which has a bunch of properties (including specifically "variant" & "type") - some of which are merged into a single "variant" prop inside of the coded Button component eg:

import { figma } from "@figma/code-connect";
import { Button } from "./";

figma.connect(
  Button,
  "https://www.figma.com/design/oHsoXoDsvnhjlbpzSIbHvU/BIOME?node-id=2-3486&m=dev",
  {
    props: {
      children: figma.string("Label"),
      variant: figma.enum("Variant", {
        Primary: "primary",
        Secondary: "secondary",
        Tertiary: "tertiary",
      }),
      type: figma.enum("Type", {
        Fatal: "fatal",
        Inverse: "inverse",
        Default: "default",
      }),
      size: figma.enum("Size", {
        Large: "large",
        Medium: "medium",
        Small: "small",
      }),
    },
    imports: ["import { Button } from '@biom3/react'"],
    example: ({ variant, type, children, size }) => {
      const fullVariant = type === "default" ? variant : `${variant}/${type}`;
      return (
        <Button variant={fullVariant} size={size}>
          {children}
        </Button>
      );
    },
  },
);

this example code-connect snippet above fails to render anything inside of figma:

Screenshot 2024-07-01 at 4 45 11 PM

After reading through your docs, i found some info which tells me why FIGMA might not like this code snippet:

Code Connect files are not executed. While they're written using real components from your codebase, the Figma CLI essentially treats code snippets as strings. ... If something you're trying to do is not possible because of this restriction in the API, we'd love to hear your feedback.

So Im just here wondering, what would be the best way to try and achieve the above?

glomotion commented 4 months ago

if i dont try to concat the type and variant into a single string, the code snippet works just fine - eg:

Screenshot 2024-07-01 at 4 58 14 PM
example: ({ variant, type, children, size }) => {
      return (
        <Button variant={variant} size={size}>
          {type}: {children}
        </Button>
      );
    },

But sadly this means code-connect isnt showing us an accurate code snippet. :(

glomotion commented 4 months ago

just to try and make this crystal clear, the variants that are supported inside the codebase look like:


export type ButtonVariant =
  | "primary"
  | "primary/fatal"
  | "primary/inverse"
  | "secondary"
  | "secondary/fatal"
  | "tertiary"
  | "tertiary/inverse";
jyyang0 commented 4 months ago

Hey @glomotion, thanks for the feedback -- As you've correctly identified, Code Connect only parses the code so conditionals inside of the template will not render correctly -- The team is currently exploring potential APIs so that we can support scenarios like this where more custom transformations are required to render your components correctly.

In the meantime, if this is blocking you this can technically be achieved using variant restrictions , so you could set up a separate figma.connect call for each

import { figma } from "@figma/code-connect";
import { Button } from "./";

figma.connect(
  Button,
  "https://www.figma.com/design/oHsoXoDsvnhjlbpzSIbHvU/BIOME?node-id=2-3486&m=dev",
  {
    variant: { Variant: "Primary" }, // This code connect will only be shown for nodes with `Variant` = 'primary'
    props: {
      children: figma.string("Label"),
      fullVariant: figma.enum("Type", {
        Fatal: "primary/fatal",
        Inverse: "primary/inverse",
        Default: "primary",
      }),
      ...
    },
    imports: ["import { Button } from '@biom3/react'"],
    example: ({ fullVariant, children, size }) => {
      return (
        <Button variant={fullVariant} size={size}>
          {children}
        </Button>
      );
    },
  },
);

figma.connect(
  Button,
  "https://www.figma.com/design/oHsoXoDsvnhjlbpzSIbHvU/BIOME?node-id=2-3486&m=dev",
  {
    variant: { Variant: "Secondary" }, // This code connect will only be shown for nodes with `Variant` = 'Secondary'
    props: {
      children: figma.string("Label"),
      fullVariant: figma.enum("Type", {
        Fatal: "secondary/fatal",
        Inverse: "secondary/inverse",
        Default: "secondary",
      }),
      ...
    },
    imports: ["import { Button } from '@biom3/react'"],
    example: ({ fullVariant, children, size }) => {
      return (
        <Button variant={fullVariant} size={size}>
          {children}
        </Button>
      );
    },
  },
);
glomotion commented 4 months ago

Oh thank you kindly for the prompt reply and the code snippet @jyyang0 !! In this particular case, this should be just what I need! ❤️ Would love to see the ability to use expressions inside of the code snippets in the future. Sadly designers often don't construct variables etc with the same thoughtfulness as engineers, so being able to mix and match figma props into the right API for the component would definitely be very useful for us.

glomotion commented 4 months ago

FWIW - i've also found that expressions inside example snippets, could be quite handy to work around type issues when converting props between figma and code (especially given that code-connect files must be TSX).

karlpetersson commented 4 months ago

FWIW - i've also found that expressions inside example snippets, could be quite handy to work around type issues when converting props between figma and code (especially given that code-connect files must be TSX).

Hey @glomotion! This sounds like something we might want to look closer into if you're running into issues here, do you have an example of this?

glomotion commented 4 months ago

apologies @karlpetersson - I think the issues i mentioned yesterday were actually due to other more complicated issues regarding how to render subcomponents (new issue here: https://github.com/figma/code-connect/issues/86). If i think of any other examples were this might be useful, ill come back and update this thread. :)