Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tailwind support for Figma variables #109

Merged
merged 6 commits into from
Jul 11, 2024

Conversation

davestewart
Copy link
Contributor

@davestewart davestewart commented Jun 28, 2024

Note

Check the comment thread, as the final PR also introduced new settings to determine when variables were used, as well as #110 which improved how colors are derived

This PR modifies the Tailwind color functions to support Figma variables.

This allows users to use custom variables in their design systems, such as neutral/700 or buttons/active-border which then output as classes such as bg-neutral-700 or border-buttons-active-border:

CleanShot 2024-06-28 at 17 33 34

The main update to the code is that rather than passing in a color and opacity, you pass the entire fill or color stop and the function's code returns the color name as-is if it's a variable, or looks up the nearest value if not.

Output looks like this:

<div class="w-44 h-36 relative">
  <div class="w-20 h-36 left-0 top-0 absolute">
    <div class="left-[16px] top-0 absolute text-neutral-900 text-xs font-normal font-['Inter']">Variables</div>
    <div class="w-20 h-28 left-0 top-[27px] absolute">
      <div class="w-8 h-8 left-0 top-0 absolute bg-test-dragon"></div>
      <div class="w-8 h-8 left-[44px] top-0 absolute bg-test-dragon-light/opacity-25"></div>
      <div class="w-8 h-8 left-0 top-[44px] absolute bg-gradient-to-b from-test-dragon to-test-sky"></div>
      <div class="w-8 h-8 left-[44px] top-[44px] absolute bg-gradient-to-b from-test-dragon to-test-sky"></div>
      <div class="w-8 h-8 left-[44px] top-[88px] absolute bg-gradient-to-b from-test-dragon via-green-300 to-test-sky"></div>
    </div>
  </div>
  <div class="w-20 h-24 left-[103px] top-0 absolute">
    <div class="left-[16px] top-0 absolute text-neutral-800 text-xs font-normal font-['Inter']">Colors</div>
    <div class="w-20 h-20 left-0 top-[27px] absolute">
      <div class="w-8 h-8 left-0 top-0 absolute bg-lime-400"></div>
      <div class="w-8 h-8 left-[44px] top-0 absolute bg-lime-400/opacity-25"></div>
      <div class="w-8 h-8 left-0 top-[44px] absolute bg-gradient-to-b from-lime-400 to-cyan-400"></div>
      <div class="w-8 h-8 left-[44px] top-[44px] absolute bg-gradient-to-b from-lime-400 to-cyan-400"></div>
    </div>
  </div>
</div>

Closes #107

Relates to #102

@bernaferrari
Copy link
Owner

will this work: bg-lime-400/opacity-25? Shouldn't it be /25? Or you created a variable that's actually 25? My biggest fear is that if someone has figma variables but don't use custom tailwind file won't be able to get benefits, but maybe I'm wrong. What do you think?

@davestewart
Copy link
Contributor Author

davestewart commented Jul 1, 2024

Hey! Thanks for jumping on to this.

Looking at the docs, it appears I made a mistake with the opacity code! It was this line I refactored; did I misunderstand?

Fixed now:

CleanShot 2024-07-01 at 23 21 49

Regarding a user using variables but not a custom tailwind file, you make a fair point.

Saying that, our designer was actually quite surprised about the color being rounded in the first place.

But of course, you need to make sure things don't break going forward.

Perhaps a "Conversion" dropdown would be useful here:

Label Behaviour Output Comment
Exact Passes arbitrary hex value to Tailwind to generate new rule bg-[#bef260] Solves #102
Closest Rounds to closest Tailwind default color bg-lime-300 Current behaviour
Custom Uses variables to indicate custom token name bg-success Solves #107

Saying that, maybe that doesn't work, as we would only need to decide what happens with variable, rounding happens anyway, so perhaps it's a kind of blended mix of the three?

Also, I don't know enough about the UI element of figma panels to know where this would go. I see there is the debug UI; I assume that is where it happens?

FWIW, this was our designer's reaction to seeing custom tokens:

image

@bernaferrari
Copy link
Owner

I wish the user had only to choose between two options, but in that case seems fair. I don't know if I have a 3 option switch. Will probably be similar to swiftui scaffold x etc thing. I'll take a look

@davestewart
Copy link
Contributor Author

davestewart commented Jul 3, 2024

I wonder if two checkboxes could do it?

  • Round color values to closest
  • Use variables as color names

Results would be:

Round colors Var names Description
. . Arbitrary colors for everything
x . Rounded colors for everything
. x Arbitrary colors for fills and custom tokens for variables
x x Rounded colors for fills and custom tokens for variables

Vs Dropdown:

Option Description
Exact Arbitrary colors for everything
Rounded Rounded colors for everything
Custom Rounded colors for fills and custom tokens for variables

Just trying to think through the problem...

@bernaferrari
Copy link
Owner

Yeah, could make sense... Most people would use the round color but not use variable. I think I like this.

@davestewart
Copy link
Contributor Author

OK, updates made.

Preferences

CleanShot 2024-07-10 at 14 15 39

I added two new preferences, and disambiguated the one for values / sizes:

  roundTailwindValues: boolean;
  roundTailwindColors: boolean,
  customTailwindColors: boolean,

I also made the labels less ambiguous (and perhaps in a future update we could update the UI to UI3?)

Colors

A couple of points to take into account:

CleanShot 2024-07-10 at 15 43 39

  1. I've aligned with the way value-rounding works for colors, so both values and colors automatically show Tailwind tokens (lime-300) rather than arbitrary values (bg-[#bef264]) if they match Tailwind config.

  2. It's a bit tricky to get the color color names right just now, as they are within common/retrieveUi/retrieveColors. However, Simplify Tailwind implementation #110 has already done the work to simplify this, so if you're happy to wait I can look to marry the preferences and color output values in that PR.

If we can get this merged sooner rather than later, I'll merge these changes into #110 and #113 then things will be looking pretty rosy!

@bernaferrari
Copy link
Owner

I'm happy. I think just the label could be shorter. Maybe use a popover to explain more, maybe I don't know. What do you think? Do you like this? I think it is just consuming too much space.

@davestewart
Copy link
Contributor Author

I wondered the same.

Your custom UI is quite bulky compared to the built-in one:

CleanShot 2024-07-10 at 19 31 54

But then even that looks like a lot of text.

Here's the checkboxes in case you want to play around:

[ ] React (JSX)
[ ] Optimize layout
[ ] Include layer names in classes
[ ] Round pixel values to Tailwind defaults
[ ] Round color values to Tailwind defaults
[ ] Use variables as custom color tokens

Or, shorter (this is probably the quickest win):

[ ] React (JSX)
[ ] Optimize layout
[ ] Include layer names
[ ] Round pixel values
[ ] Round color values
[ ] Custom color variables

I wonder if groups might help? Though I know it's only Tailwind which has the majority of the options right now.

Layout:

[ ] React (JSX)
[ ] Optimize layout
[ ] Include layer names in classes

Values:

[ ] Round pixel values to Tailwind defaults
[ ] Round color values to Tailwind defaults
[ ] Use variables as custom color tokens

Or, shorter:

Layout:

[ ] React (JSX)
[ ] Optimize layout
[ ] Include layer names

Tailwind:

[ ] Round pixel values
[ ] Round color values
[ ] Custom color variables

??

@bernaferrari
Copy link
Owner

Could be something like "optimize" and opens a pop-up where you can select what you want to optimize, I don't know..
Or "round values...", you click, and can choose which value you want. A dropdown could work.

@davestewart
Copy link
Contributor Author

davestewart commented Jul 10, 2024

Could be something like "optimize" and opens a pop-up where you can select what you want to optimize

I kind of see what you mean, but as they are preferences, aren't they all "optimizations"? And maybe users might want to change per-component, so might be good to make it really accessible.

Just seeing if there are any examples of Figma already doing this:

image

Maybe:

Layout

[ ] React (JSX)
    Use className instead of class
[ ] Optimize layout
    I still don't know what this is
[ ] Include layer names
    Include layer names in list of Tailwind classes
    
Tailwind

[ ] Round pixel values
    Round pixel values to configured Tailwind pixel values
[ ] Round color values
    Round color values to configured Tailwind color values
[ ] Custom color variables
    Use Figma variable names in place of Tailwind color names

Looks bulky as hell there, but would be smaller font size and dropped-back color.

I think maybe at this stage just have the extra checkboxes and make improving the Plugin UI a separate ticket.

Could combine aligning it with the Figma UI3.

@bernaferrari
Copy link
Owner

what if we did something like an accordion/collapsible https://ui.shadcn.com/docs/components/collapsible where you have the "advanced features" there? Not sure we have enough, but could work...

Optimize layout works like this:
you have a frame with two rectangles inside, everything using absolute position. If you press shift+a, figma is going to make an auto layout for you automatically. Inferred try to guess that and if it is possible to make an autolayout automatically, it will do.

@davestewart
Copy link
Contributor Author

davestewart commented Jul 10, 2024

By "advanced features"  you mean the rounding / variables options?

Also, would need to work out how the UI would look with an accordian.

How would that look? I think the checkboxes would need to be block not inline if that was the case.

@bernaferrari
Copy link
Owner

Yes. You would have a block section, that expands with inline things. But that's just an idea. I'm open for other ideas too. As long as the UI is easy, feel free to think on anything

@davestewart
Copy link
Contributor Author

davestewart commented Jul 10, 2024

OK, I took a quick stab at shorter labels and title props:

CleanShot 2024-07-10 at 23 49 57

Second option was longer labels but simpler checkboxes:

CleanShot 2024-07-11 at 00 01 59

Third option, simpler checkboxes and smaller labels with longer descriptions:

CleanShot 2024-07-11 at 00 07 42

My feelings about a dropdown are:

  • I'm not sure it's possible to make the choice for the user to determine what is "advanced"
  • Delivering a significantly new UI setup feels like an new ticket
  • Users probably won't be tinkering with this UI that often anyway

Of the above screenshots:

  • I prefer the 3rd
  • Could do more work later

Also, probably lose all the backgrounds and borders (they just make it look busy for no reason):

CleanShot 2024-07-11 at 00 16 34

Anyway. Heading to bed now. Would love to move ahead on this tomorrow!

@bernaferrari
Copy link
Owner

I think I like the most the first. Which one did you like the most?

@davestewart
Copy link
Contributor Author

davestewart commented Jul 11, 2024

I prefer the last one with the simpler UI that paves the way for something UI3-compatible.

But I've updated the code with the shorter labels and tooltips, so that's effectively ready to go now.

CleanShot 2024-07-11 at 13 16 15

@bernaferrari
Copy link
Owner

I like the last one, but I think there are too many options before the user sees the code which is the main part. Thanks. Should I merge already?

@davestewart
Copy link
Contributor Author

before the user sees the code which is the main part

Yeah, I suppose the last 3 options are probably the ones which the user would be most interested in.

I think better groups as outlined earlier would be the best solution to this, but think that should be a separate ticket, and as mentioned taking a look at implementing a UI3 theme.

So for now, I think yeah, get this merged 🫡

@bernaferrari
Copy link
Owner

Ok, perfect. Thanks!

@bernaferrari bernaferrari merged commit d2c3f52 into bernaferrari:main Jul 11, 2024
1 check passed
@davestewart davestewart deleted the feat/tailwind-variables branch July 11, 2024 15:43
@davestewart
Copy link
Contributor Author

OK. On to the next PR!

bernaferrari pushed a commit that referenced this pull request Jul 12, 2024
* Modify Tailwind color functions to support Figma variables

* Refactor function to arrow function

* Reorganise all config to separate file

* Simplify Tailwind code

* Clarify Tailwind color usage

* Add Tailwind support for horizontal auto-layout hug (#111)

Co-authored-by: Dave Stewart <dev@davestewart.co.uk>

* Add Tailwind support for Figma variables (#109)

* Modify Tailwind color functions to support Figma variables

* Refactor function to arrow function

* Fix fill opacity code

* Add new Tailwind preferences

* Prefer Tailwind color when color matches exactly

* Update UI with shorter labels and tooltips

---------

Co-authored-by: Dave Stewart <dev@davestewart.co.uk>

---------

Co-authored-by: Dave Stewart <dev@davestewart.co.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use variable names as-is, in Tailwind code.
2 participants