Figma Schema Exportables

Exportables are schema definitions that allow Handoff to parse semantic meaning from Figma components.

Exportable schemas allows Handoff to connect to any component sets in Figma and generate tokens. In simple json, developers can define the structure of a Figma component and what tokens to extract from each element. This allows Handoff to adapt to the component set of any Figma file, and define semantic meaning for the Figma component. This will enable many features going forward, including -

  • Figma Linting
  • Component Change Detection and Changelog
  • Automatic Figma Schema Detection

Exportables are stored in ./exportables. In 0.5.0 we only support exportable components, so put component definitions in ./exportables/components. An exportable consists of 3 components -

  • Metadata - describe the component (id, group)
  • Options - control how the component is rendered in Handoff (tokens, preview)
  • Parts - define the semantic structure of the Figma component

How to use exportables

Using exportables will allow quick tokenization of new components. For example, here is an annotated exportable for badges, a component not currently supported by handoff.

Badge.json

This is an example exportable to fetch badges from a

1{ 2 "id": "badge", 3 "group": "Components", 4 "options": { 5 "exporter": { 6 "search": "Badge", 7 "supportedVariantProps": ["THEME", "TYPE", "STATE(:disabled)"] 8 }, 9 "transformer": { 10 "rootCssClass": "badge", 11 "cssVariableTemplate": "badge-{$type}{$size}-{$part}-{$theme}-{$state}-{$property}", 12 "scssVariableTemplate": "badge-{$type}{$size}-{$part}-{$theme}-{$state}-{$property}" 13 }, 14 "demo": { 15 "tabs": { 16 "overview": { 17 "design": { 18 "state": "default" 19 }, 20 "layout": {} 21 }, 22 "designTokens": { 23 "design": { 24 "state": "default" 25 } 26 } 27 } 28 } 29 }, 30 "parts": [ 31 { 32 "id": "$", 33 "tokens": [ 34 { 35 "from": "$", 36 "export": ["BACKGROUND", "BORDER", "SPACING", "EFFECT"] 37 }, 38 { 39 "from": "TEXT", 40 "export": ["TYPOGRAPHY", "FILL"] 41 } 42 ] 43 } 44 ] 45} 46

If you add this file to exportables/components and add components/badge to the figma.definitions in your config.js, Handoff will start looking for a Badges component set, and generate tokens, css, scss, and types for you.

With no other changes, handoff will create a set of badge token files for you. For example, it will render something like this for css variables - https://gist.github.com/bradmering/020429c30f11d95bfb2577ea57809878. You can see that creates a comprehensive list of all the tokens you would need to render badges in a css frontend framework.

Adding a template to preview the new exportable

If you want badges to work in the Handoff component preview as well, you would need to add a badge template to integration/templates/badge/default.html. That file would look like this for Bootstrap 5.2 -

1<script src="/components/bundle.js"></script> 2 3<body class="theme-{{ theme }} preview-body"> 4 <span class="badge badge-{{ type }}">{{ characters }}</span> 5</body> 6

Mapping the new exportable to scss

You would also want to map these tokens to the framework. This is how you might do that in Bootstrap 5.2, adding this file to integration/sass/extended/badge.scss

1/* ============================================================================= 2 BADGES (project/_badges.scss) 3 ========================================================================== */ 4 5$prefix: ""; 6// Load raw SCSS variables for mapping 7@import "./exported/tokens/types/badge"; 8@import "./exported/tokens/sass/badge"; 9@import "./exported/tokens/css/badge"; 10 11@if variable-exists(badge-variants) and ($badge-variants != null) { 12 @each $variant in $badge-variants { 13 .badge-#{$variant} { 14 background: var(--badge-#{$variant}-background); 15 @each $state in $badge-states { 16 @if $state != "" { 17 $state: "-" + $state; 18 } 19 --#{$prefix}badge-padding-x: #{$badge-#{$variant}#{$state}-padding-x}; 20 --#{$prefix}badge-padding-y: #{$badge-#{$variant}#{$state}-padding-y}; 21 @include rfs( 22 $badge-font-size, 23 --#{$prefix}badge-#{$variant}#{$state}-font-size 24 ); 25 --#{$prefix}badge-font-weight: #{$badge-#{$variant}#{$state}-font-weight}; 26 --#{$prefix}badge-color: #{$badge-#{$variant}#{$state}-color}; 27 --#{$prefix}badge-border-radius: #{$badge-#{$variant}#{$state}-border-radius}; 28 } 29 } 30 } 31} 32