onyx-gen / onyx Goto Github PK
View Code? Open in Web Editor NEWA Figma plugin that helps to transform Figma Design Systems to Vue components with UnoCSS utility classes.
License: MIT License
A Figma plugin that helps to transform Figma Design Systems to Vue components with UnoCSS utility classes.
License: MIT License
We need to do some marketing and documentation and for that we could focus on creating a very simple website built with Nuxt and deployed on Vercel Edge.
Technical Details need to be refined.
Blocked by #14
The Onyx repository should be made public so that it can be cloned by other developers.
We can use generation in Variables
mode via the UI:
We use the applied design tokens from (Tokens Studio for Figma) when the generation mode is set to Variables
. We may generate a utility class like font-$Interactive.CTA
. The identifier Interactive.CTA
is the exact typography composite token applied to the selected Figma layer for which we want to generate a utility class.
We not always want to use the exact raw variable/token name as provided by Tokens Studio. We may want to lowercase the token identifier name.
Let's come up with a simple solution to alter token names via configuration in the UI.
TODO: Technical Concept
It is possible to enable the vertical trim option in Figma.
There is no direct CSS equal for a vertical trim fix. One might use https://github.com/seek-oss/capsize to add a approximated vertical trim fix using font metrics.
We should give the option to alter the generated font utility class. For example: font-$custom-font
to font-cap-$custom-font
. The updated utility class name is something user-specific that adds the capsize fix to the generated utility class.
How to alter the original utility class name to the target one containing the cap
infix should be configurable in the Figma Plugin UI via maybe a regex pattern or something similar.
<_DS_resizer />
is generated as the Figma design contains a component instance called _DS_resizer
. This is a Figma-only helper component used by Visual Design. We do not want to use this component in the generated target language.
There should be a mechanism so that it is configurable to ignore specific components, nodes, etc. via the UI in Figma.
Technical details must be defined.
Many text properties can be set on individual characters. For that reason, you will find that many of text properties can return the special value figma.mixed if there are characters in the text with different values for that property. Always consider that a text property could have mixed values.
See https://www.figma.com/plugin-docs/working-with-text/
See also #24
We need to publish the ìcons pnpm workspace package as on GitHub packages.Other modules in this Onyx project would then use an exact version instead of the workspace:^version. This is necessary as the workspace:^version does not include the fetched icons and processed into the dist` directory.
Currently only line heights with unit PIXELS
can be generated in all three possible generation modes (inferred
, arbitrary
, variable
). See details for the possible types here.
If the unit is percent we only allow generating in arbitrary
mode. We should support the other two generation modes as well!
The unit could be "PIXELS" | "PERCENT" | "AUTO" and it should be possible to output utility values also for inference & tokens mode.
Possible generation modes:
https://github.com/MiguelFranken/onyx/blob/a03827c40994cbe1accec8eb404095070b6982b7/packages/code/src/builder/types.ts#L50-L54
Relevant method to change: https://github.com/MiguelFranken/onyx/blob/bc8e6aa7b4db03ab8654bce0383de2fbbd3f19a3/packages/code/src/builder/inference/line-height.ts#L6-L23
Tailwind utility class to generate:
https://tailwindcss.com/docs/line-height
Unitless line height value:
https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#number
Input: Percent Line Height (e.g. 128%)
Step 1:
Transform 128% to Unitless Number.
Output:
1.28
Step 2 (Inference):
Get the nearest inferred value available in Tailwind.
Input: 1.28
Output: 1.25
Step 3 (Generate utility class):
leading-tight
Possible values:
leading-none line-height: 1;
leading-tight line-height: 1.25;
leading-snug line-height: 1.375;
leading-normal line-height: 1.5;
leading-relaxed line-height: 1.625;
leading-loose line-height: 2;
Utility classes like text-left
are generated and shown in the generated code block. This is totally fine, but we might want to add the option to hide a set of opinionated default utility classes.
The text-left
utility class might have no effect as the CSS default is to show text on the left side. So it might be hidden.
But we would need to add this utility class if in a parent a utility class like text-right
would be applied having an impact on the text position of the child. In that case text-left
would be necessary.
We need to remove the old UnoCSS builder class:
This is necessary as we already have a new builder on use:
onyx/packages/code/src/parsers/figma-node.parser.ts
Lines 69 to 72 in 48548b1
In short: Delete everything releated to the old builder such as Event Bus Message types, the actual builder class, etc.
Changes mainly in packages/code and packages/ui.
GitHub settings > Activate Dependabot
Status: Work in Progress
This proposal introduces a method to convert Figma design nodes into Vue components by incorporating a slot-based system that facilitates dynamic content insertion. It specifically utilizes the text properties within Figma components to define slots, tagged as <slot>
for unnamed slots and <slot-name>
for named slots, to enhance modularity and adaptability of UI components.
Figma allows defining editable properties for components such as Variant
, Text
, or Instance Swap
.
Used within a Component Set to generate different component versions based on predefined attributes (e.g., color, size).
Designate editable text fields within components, essential for customizable UI texts like button labels or dialog contents.
Allow swapping of component instances within the same placeholder, useful for dynamic iconography or user interfaces.
Property Type | Use | Flexibility | Component Complexity |
---|---|---|---|
Variant | Different states/styles of a component | High | High |
Text | Editable text within components | Medium | Medium |
Instance Swap | Swappable components within a placeholder | Medium-High | Medium-High |
Methodology: Utilize a consistent annotation for slots within Figma components using either a simple tag for unnamed slots (<slot>
) or a specific tag for named slots (<slot-name>
), which allows for precise content targeting.
Vue Integration: Leverage Vue's slot mechanism to integrate these Figma slots into the generated code, allowing dynamic content injection seamlessly.
For a button with a slot:
<button>
<slot /> <!-- Default slot for dynamic content insertion. Relates to a default/unnamed Figma text propery slot -->
</button>
For using named slots within a Vue component:
<template>
<button>
<slot name="icon"></slot> <!-- Named slot for specific content targeting -->
<slot name="text"></slot> <!-- Another named slot -->
</button>
</template>
Our current implementation utilizes a custom data structure for representing generated HTML code, which is then converted into a string with our custom formatting logic. While this method serves its purpose, it's becoming apparent that adopting a more standardized approach could offer significant benefits. Specifically, integrating the hast (Hypertext/HTML Abstract Syntax Tree) package from the Unified Collective could streamline our processes and offer additional functionality through its ecosystem of plugins.
The built production Onyx bundle should be published as production Figma plugin so that other Fima users can use the plugin in Figma without building the project!
https://help.figma.com/hc/en-us/articles/360042293394-Publish-plugins-to-the-Figma-Community
Each Figma plugin can be showcased via a Figma Community Plugin page. It shows a description and some metadata. We need to gather this metadata for the Onyx project.
Example community plugin page:
https://www.figma.com/community/plugin/1037108608720448600/figma-to-html-with-framer
# Onyx ◆ Design System to Code
## Overview
Onyx is designed to simplify the workflow between design and development by automating the conversion of your Figma Design System into ready-to-use Vue components. Its ability to handle multiple selected component variants and integrate design tokens provided via the Tokens Studio for Figma plugin makes it a powerful tool for modern web development.
Onyx is a Figma plugin designed to efficiently translate Figma Design Systems into Vue components, utilizing UnoCSS utility classes. This tool targets developers and designers looking to streamline the conversion of their design systems into functional, reactive UI components directly usable in Vue projects.
## What It Does
- **Figma Components to Vue Components:** Onyx allows users to select components within Figma and generate corresponding Vue components. Design properties are translated to UnoCSS utility classes.
- **Support for Design Tokens:** The plugin integrates with Tokens Studio, another Figma plugin, to convert design tokens into CSS variables. These variables are then passed to the UnoCSS utility classes (e.g., background color design token named `primary.bg.hover` generates the `bg-$primary.bg.hover` UnoCSS utility class)
- **Multi-Variant Component Support:** Users can select multiple variants of a component (such as `default`, `hover`, and `focused`) and Onyx will generate a single Vue component. Onyx automatically applies the correct UnoCSS variants (e.g., `bg-red-600 hover:bg-red-700 focus:bg-red-800`
- **Live Preview:** Onyx provides a real-time preview of the generated Vue components within Figma via an iframe. This feature ensures that components are visually and functionally in sync with the Figma design.
## How to Use It
1. **Select Components:** Start by selecting one or multiple components within your Figma design system.
2. **Open the Onyx Figma plugin**: Open the Onyx Figma plugin in Figma's plugin panel.
3. **Generate Code:** Onyx automatically generates Vue components for the selected Figma components.
4. **Implement in Project:** Copy the generated Vue component into your Vue project.
## Limitations
- **Work in Progress:** As the plugin is still under development, some design properties may not convert perfectly into UnoCSS utility classes. At the moment not all design tokens types can be applied.
- **Design Compatibility:** There may be limitations in how certain Figma design properties translate to UnoCSS utility classes, potentially requiring manual adjustments.
What needs to be added:
README.md
TODOs for this issue:
Currently the hover
variant is applied directly on the (child) nodes. But we should add a group
utility class to the root HTML element and use for the children the group-hover
utility variant.
This fixes the issue that the hover effect in the video is applied for the inner next as well when the group is hovered.
Status: Work in Progress
This RFC outlines a proposed method for converting Figma designs into Vue code, focusing specifically on the treatment of Figma component instances. Figma's design system is component-based, mirroring the modular architecture of modern web frameworks such as Vue. Our approach involves recognizing and appropriately structuring these Figma component instances within the generated Vue codebase, ensuring each Figma component (and its instances) translates into distinct Vue components.
Figma operates on a component-instance model where the main component acts as a template, and instances are copies that inherit its attributes but can also override them. This model is beneficial for maintaining consistency across designs while allowing variations. Our goal is to replicate this model in Vue to maintain design integrity, enhance code maintainability, and simplify project scalability.
Component and Instance Identification:
Example of Generated File Structure:
ButtonGroup.vue
: Represents the selected main component, which includes Button.vue
as a child component (imported instance).Button.vue
: Stands as a reusable component instance.Customization Options:
License project under MIT.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.