All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
This release introduces greater flexibility for custom integrations and general improvements to CLI handling.
-i <path-to-integration>
CLI argument.
fetch
, start
, build:app
, etc.integration
directory if the argument isn't specified, ensuring backward compatibility.yargs
for improved CLI parsing.This release enables creation of complex documentation pages, with storybook compatible formats. It has two main features - MDX support for adding react components to your documentation pages, and Snippet Previews - a system for using Handoff's existing html build process to create complex component previews.
.html
in the /integration/snippets
file or
run the make:snippet [name]
cli commandSnippetPreview
componenthtml
file is a Mustache template. At present there are two variables
that can be used in these files{{{style}}}
a compressed inline style of either the compiled sass code
or the raw css code provided.{{{script}}}
a compressed inline script of the output of the js compilationSnippetPreview
. This
component accepts 2 - 3 properties, plus a react fragment as the children.
title
accepts a string as the h2
title. Set to false or exclude if you
don't want itid
is the name of your snippet {name}.html
The snippet will load dynamicalheight
accepts a string to set the height of the preview. If you leave it
off, Handoff will set the height of the preview automatically from the contents
of the snippet.1<SnippetPreview title="A Testimonial Component" id="testimonial" height="725px"> 2 <p>Render a testimonial inline with other content.</p> 3</SnippetPreview>
build:snippets <name>
will either rebuild all the snippets for you, or if an
optional name is passed, will rebuild a single snippetrename:snippet <source> <destination>
will rename a snippet and its js and scss
filesstart
command where every doc page would be flagged as
changed on watch.This release addresses several developer experience issues
eject:integration
or make:integration
the default integration is exported, but it is not built. This causes a weird developer experience if you try to build:app
without build:integration
first. This patch adds the build:integration
logic to execute after eject
or make
as well as before build:app
to ensure that if an integration exists, the integration is built before building or serving the appbuild:app
fails while building the integration preview sass code the error messages were not clear, and didn't explain that you could use --debug
to make them more clear. The error message has been improved and now alerts users to the --debug
flag to help them debug their integration.--force
flag, the force now triggers an overwrite rather than failing.This release fixes a couple of small path issues that affect running 0.13.0 from the global path.
<Link>
componentIntegration System Overhaul
handoff-app make:integration
(or eject:integration
which is still supported as an alias).handoff.config.json
such as name and version are no longer recognized, making the integration section of handoff.config.json
obsolete.integration.config.json
:
figma.options
section in handoff.config.json
as well as all transformer related options within the legacy schemas as this file now contains all integration-specific details, including those options previously managed manually across different places.figma.options
section in handoff.config.json
no longer supported and also means that all transformer options have been removed from legacy schemas (exportables), rendering this section no longer supported as well.view.config.json
files, located in the respective component’s directory within the integration’s templates folder.demo
options section in all legacy schemas has now been removed and is no longer supported by Handoff.Legacy Schema Updates
use_legacy_definitions
option in handoff.config.json
is no longer supported.figma.definitions
section in handoff.config.json
is deprecated.handoff-app make:integration
.integration.config.json
) to the new directory (merge).integration.config.json
if needed.handoff-app make:integration
. This will use a Bootstrap 5.3 template.integration.config.json
options if necessary.handoff-app eject:exportables
.integration.config.json
.view.config.json
files of respective components.handoff.config.json
:
figma.options
to the integration.config.json
file as necessary.figma.options
, figma.definitions
, figma
, integration
, and use_legacy_definitions
.fetch
and build:integration
steps.cssRootClass
property in the Handoff Figma plugin metadata.HANDOFF_
prefix.
FIGMA_BASE_URL
-> HANDOFF_FIGMA_BASE_URL
DEV_ACCESS_TOKEN
-> HANDOFF_DEV_ACCESS_TOKEN
FIGMA_PROJECT_ID
-> HANDOFF_FIGMA_PROJECT_ID
OUTPUT_DIR
-> HANDOFF_OUTPUT_DIR
SITES_DIR
-> HANDOFF_SITES_DIR
USE_HANDOFF_PLUGIN
-> HANDOFF_USE_HANDOFF_PLUGIN
CREATE_ASSETS_ZIP_FILES
-> HANDOFF_CREATE_ASSETS_ZIP_FILES
handoff-app eject:config
) and update it by setting the integration
property to {name: 'bootstrap', version: '5.3'}
.handoff-app eject:config
) and update the figma.options
property to the previous default value..env
files instead of overriding them if the file already exists..css
and .scss
files, along with correct indentations. This ensures that the generated files are valid for any local linting tools your project might use.handoff-app eject:integration
command is now the same as the one ejected by the handoff-app eject:config
command.iframe-resizer
package.axios
and next
packages.handoff-app start
command to malfunction has been fixed.Reference error: name is not defined
issue that occurred when a component specified in the schema was missing from the Figma file has been resolved. The name
reference has been replaced with a correct identifier.USE_HANDOFF_PLUGIN="FALSE"
in your .env
file../src
to ./.handoff
handoff.state.json
file.process.env
), defined in the project's respective next.config.js
file.getConfig
with the more secure getClientConfig
function.USE_HANDOFF_PLUGIN="TRUE"
in your .env
file.Authorization
header to send the token as part of any Figma API request. In any other case, X-Figma-Token
header will be used.tokens/maps
directory of the designated export directory as individual files while the tokens-map
file, which contains all available tokens, gets exported into the designated export directory root.next.config.js
file alongside improved path resolving for custom themes..npmignore
file to reflect latest .gitignore
changes made in the last release.This release focuses heavily on better support for environments on which multiple projects are being exported and built. All of the changes introduced in this release should provide better experience when working on such environments as well as resolve some of the issues which would occur when different projects would use same working directories.
public
directory, it’s now also possible to create a public-{figmaProjectId}
directory which gets used only when the project with the respective Figma project id is being built. If the public
directory is used, assets located in that directory will be applied to all projects.poweredBy
option is now called attribution
and has been moved into app
config key.next_base_path
option is now called base_path
and has been moved into the app
config key.app
config key: theme
, title
, client
, google_tag_manager
, type_copy
, type_sort
, color_sort
, component_sort
logo
and favicon
options have been removed (it’s still possible to use custom assets but their name must match the default names).Miscellaneous improvements to ejecting of integrations, integration handling and building of previews to make it easier for the exported integration to be included in a bootstrap project.
Handoff users reported a bug in handoff-app build:app
last week. The bug didn't manifest in regression testing. This error was traced to typings in a dependency of next
.
EXPORT_PATH
within the .env file.This release is focused on enabling Handoff users to disable any of the built in components (esentially prevent them from being exported). While this was possible in previous releases, it could cause issues when running the integration builds.
This improvements was achieved by:
//<#HANDOFF.TOKENS.TYPES#>
//<#HANDOFF.TOKENS.SASS#>
//<#HANDOFF.TOKENS.CSS#>
//<#HANDOFF.MAPS#>
//<#HANDOFF.EXTENSIONS#>
As a side effect, the node-sass-glob-importer
package depenedency is no longer needed as there is no longer need for "globbing" to be used when doing imports of exported component tokens since //<#HANDOFF.TOKENS.TYPES#>
, //<#HANDOFF.TOKENS.SASS#>
and //<#HANDOFF.TOKENS.CSS#>
import tokens now provide basically the same functionality.
Because of changes mentioned above, this release does require some modifications to the already ejected integrations in order for the project to be completely compatible with the new version of Handoff.
Here are the steps that need to be done:
Replace glob import lines with the respective import tokens. Note that design foundation tokens are manually imported as the tokens only handle imports related to the exported components.
Before the new release:
1@import "./exported/tokens/types/*"; 2@import "./exported/tokens/sass/*"; 3@import "./exported/tokens/css/*";
With the new release:
1@import "./exported/tokens/types/typography"; 2@import "./exported/tokens/types/effects"; 3@import "./exported/tokens/types/colors"; 4//<#HANDOFF.TOKENS.TYPES#> 5@import "./exported/tokens/sass/typography"; 6@import "./exported/tokens/sass/effects"; 7@import "./exported/tokens/sass/colors"; 8//<#HANDOFF.TOKENS.SASS#> 9@import "./exported/tokens/css/typography"; 10@import "./exported/tokens/css/effects"; 11@import "./exported/tokens/css/colors"; 12//<#HANDOFF.TOKENS.CSS#>
Add the //<#HANDOFF.MAPS#>
replace token below the @import 'variables'
statement. This will ensure that all variables related to the exported (built-in) components are correctly loaded.
Before the new release:
1$prefix: ""; 2@import "variables";
With the new release:
1$prefix: ""; 2@import "variables"; 3//<#HANDOFF.MAPS#>
Replace all import statements used to extend the default Bootstrap components with the new //<#HANDOFF.EXTENSIONS#>
import token to ensure that only those files that are related to the components that are actually being exported get imported.
Before the new release:
1@import 'extended/alert'; 2@import 'extended/button'; 3@import 'extended/checkbox'; 4...
With the new release:
1//<#HANDOFF.EXTENSIONS#>
Due to changes made to the variables.scss
file and most of the scss files in the maps
directory for the the Bootstrap version 5.2 and 5.3 interations, it's recommended to do a integration eject (after updating to Handoff 0.8.2) to ensure that your project continues to work correctly. Please remember to do a backup of your current work before doing this.
Token
interface so that all properties other than property
or value
are now moved to metadata
.Token
interface.This release is focused primarily on improving the way Handoff fetches data from figma. These changes are subtle, and do not bring any major use experience change. As we used Handoff with a wider variety of Figma design systems, we noticed that the schemas couldn't quite capture all of the various component structures.
In Figma, every component has a set of properties. These are used for categorizing the component and declaring use and behavior. These are things like - type, theme, state etc. Handoff's schemas allowed you to choose which of those properties would be pulled from a component, but did not allow you to rename or declare custom properties. This is because these properties often create semantic or behavioral meaning.
This release allows you to name and configure these properties, and map them to the sematic or behavioral meaning. This allows designers to name things according to internal conventions, localize prop names, and declare new custom properties to ingest.
supportedVariantProps
now accepts an object rather than an array. This object has two properties design
and layout
. Users should declare the props that should be pulled as an array of each of these props. The props should be the name as it is in Figma, not the old key names Handoff used to require.tokenNameSegments
. This a tokenized array of strings that allow you to generate token names for each component following a pattern.demo
section, under the tabs, you can now declare the default value for each property.demo
section, under designTokens
you can explicitly declare all the values of a property to show on the demo page.State(:disabled)
which would automatically apply the "disabled" state to all design components, distinctive only by the theme (which means light theme would have one shared disabled state while dark theme would have a different one).State(:disabled/Theme)
which removes the need for us to know what the theme variant property is and to allow users to distinct over any variant property they have and desire.1.64.2
. 1.65.0
introduces a breaking change and we need to update the maps before upgrading to it.public
dir in the working root so that assets can be published to the appThis release allows custom theme files in the working directory to override the main theme
eject:theme
which will eject the currently set theme into theme/main.scss
theme
has been added to allow toggling between themes. At present only a single default theme is providedThis release improves existing functionalities and issue detected within the design system app.
integration/scss
are now read in at build time allowing developers to provide custom scss mappings for components.theme/main.scss
is found in the working root of the project, that file will be included at build time to allow styling the app.make:page
command to CLI for creating custom pages or editing existing pagescolor
and border-color
border-style
property when fetching from figmaThis release improves existing functionalities and issue detected within the design system app.
DocumentationWithTokensProps
interface to reduce redundancy in the codebase. [CONVHAND-283]make:template
command to CLI for creating custom templatesThis release introduces support for AWS Style Dictionaries - https://amzn.github.io/style-dictionary/#/. Style dictionary is a widely used token format that can be compiled down to a number of application formats using the AWS Style Dictionary CLI tool.
You will find the new style dictionary output in the exported artifact at ./exported/tokens/sd
.
ValueProperty
is now Token
and it can now carry additional metadata (added isSupportedCssProperty
metadata property).TransformerOutput
interface type. All other interfaces such as CssTransformerOutput
and ScssTransformerOutput
have been removed entirely.0.6.0 introduces two major new tools that will make it much easier to integrate Handoff with existing projects and data pipelines. This release also reorganizes the Handoff code to make the pipeline significantly more robust, easier to extend, and easier to use in existing projects. Our goal with this release is to establish a stable Typescript API as we approach a 1.0 release.
Handoff now comes with a CLI toolchain that allows you to run Handoff commands in any context. This CLI replaces the installer from previous versions to scaffold up projects in a directory.
npm i -g handoff-app
handoff-app <command>
env
variableshandoff-app --help
for a full list of commandsHandoff now exposes a full typescript API published as commonjs modules. This API will allow you to use Handoff in your Node 16+ javascript or typescript projects. With just a few lines of code you can have Handoff run programmatically.
This API supersedes and replaces the plugin architecture introduced in 0.5.0. The API call structure is maintained, but now the API can be used directly in existing Node applications and can be used with typescript.
Here's a simple example that will fetch the data down. This example expects a DEV_ACCESS_TOKEN and a FIGMA_PROJECT_ID env variable, or those to be provided in process.env
. If not supplied, they will be prompted for when the pipeline is run.
1import Handoff from "handoff-app"; 2const handoff = new Handoff({ 3 title: "Handoff Bootstrap", 4 integration: { 5 name: "bootstrap", 6 version: "5.3", 7 }, 8}); 9await handoff.fetch();
1// This hook will execute after the integration step and allow you to extract 2// data from the pipeline and write it to a file 3handoff.postIntegration( 4 (documentationObject: DocumentationObject, data: HookReturn[]) => { 5 const colors = documentationObject.design.color.map((color) => { 6 return { 7 name: color.name, 8 value: color.value, 9 }; 10 }); 11 data.push({ 12 filename: "colors.json", 13 data: JSON.stringify(colors, null, 2), 14 }); 15 return data; 16 } 17);
This release adds Bootstrap 5.3 support with dark mode disabled by default.
To use an integration change client-config.js
to desired integration and version. For example:
integration: {
name: 'bootstrap',
version: '5.3',
},
Currently supported integrations:
fs.readFileSync
instead of the import
statement.getStaticProps
for fetching of the configuration and the exported tokens.componentExists
utility method as it's no longer usedmapComponentSize
utility method as it's no longer usedfetch
command while the dev
command was already running which would cause the app from stop responding correctly and would require app restart.0.5.0 brings two major improvements
Also in 0.5.0 is improved bootstrap 5.2 support, a simple tailwind color integration, and a cluster of bugfixes.
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 -
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 -
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. https://www.handoff.com/docs/customization/exportables/#badgejson
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.
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 -
https://www.handoff.com/docs/customization/exportables/#adding-a-template-to-preview-the-new-exportable.
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
https://www.handoff.com/docs/customization/exportables/#mapping-the-new-exportable-to-scss
Handoff allows users to integrate with particular frontend frameworks. We call these integrations. We currently support bootstrap 5.2 out of the box.
0.5.0 now allows these integrations to hook into the data extraction pipeline and modify the output, and optionally write files to the exported directory. This will allow developers to tailor the Figma data pipeline to their needs.
To use this feature, create a plugin.js
in the integration
folder of your
project. This plugin will have access to any of the core node.js libraries
you need. Export a sandbox module like this -
sandbox.exports = {
postCssTransformer: (documentationObject, css) => {
// Modify the css variables prior to save
return css;
},
}
In this example, the plugin has the full documentation object available, allowing it to query the object and then modify the css variables as needed.
Here's a simple plugin example that will read the tokens and write a simple json file with an array of colors in it. - https://www.handoff.com/docs/customization/plugins/#simple-example
Here is a comprehensive plugin.js showing all the options in 0.5.0 - https://www.handoff.com/docs/customization/plugins/#full-example
In 0.5.0 the Bootstrap 5.2 integration was rewritten to simplify and rationalize the way that tokens are being used. Since Bootstrap 5.2 is the first end to end Handoff integration, these improvements will form the template for other integrations.
This release has a simple version of a Tailwind integration. It only supports colors and typography right now. Its in this release to start testing with simple tailwind projects.
To test it out, change the integration in the config.js
to this -
integration: {
name: 'tailwind',
version: '3.3',
},
}
Continuing incremental improvement over the 0.4.0 release. This release fixes a couple of small build inconsistencies, improves debug mode when running the build and fetch, and creates a fast run mode.
-- --debug
will now send the error trace from the
webpack when building a preview. This is especially useful when there is an error
either in the template or scss maps.-- --fast
will execute the script but if there is
already a built temp directory, it will use the built dir rather than recreating
it. This speeds up runtime significantly. If this option is supplied but the
temp dir does not yet exist, it will be created.npm run transform:preview
or
node node_modules/handoff-app/scripts/fetch.js preview
will properly execute
just a single portion of the pipeline rather than the whole pipeline.<ul>
wrapper for the
subsequent lists.When 0.4.0 was released, we found a structural problem with the way integrations were published into projects. 0.4.1 resolved a couple of issues, but a couple of significant new pieces of code were required to fully resolve the issue.
The resolution is fixing paths so that they work properly when running the handoff source as well as running handoff in a project.
This release introduces two major new features - framework integrations and much better color support. The color support is straightforward - Handoff now supports much broader color options from Figma including gradients (linear and radial), as well as layered colors, alpha channels and blend modes.
Framework integrations is Handoff's new plugin architecture for integrating tokens with popular web and application frameworks. Previous versions of Handoff were tightly coupled with Boostrap 5.2 as a proof of concept.
To integrate tokens into applications, the tokens need to be mapped to the the files you'll need. In web applications, this means mapping css and sass variables to existing variables, or extending classes with the tokens.
When fetch is run, any files added to the integration
folder will be merged
with the selected integration. The sass files will be published to
/exported/{integration}-tokens
Integrations also move the templates into integrations so each framework integration can define the markup for each component, type, and state. This allows handoff to include default markup for common frontend frameworks.
exported/variables
file was renamed to exported/tokens
exported/{integration}-tokens
containing the
maps and extended sass integration files./integration
folder that will be merged with
the configured integration sass and templates.integration
is an object that contains two properties name
and
version
. If you set integration.name
to custom
and version
to null
the project will expect a fully defined integration in the /integration
dir.figma
is an object that allows customization of how components are fetched.
figma.components
contains a list of the componentsfigma.components.button
will
define how buttons are fetched from figma.search
property determines the library component and name of the frame
to look in for the component. Setting figma.components.button.search
to
Unicorn
will try to find a button structure in a library object called
Unicorn
.size
property of each component will define a size map allowing projects
to map figma sizes to token names.hex
, type
, and rgb
properties were dropped from the ColorObjectvalue
contains the CSS set of color values, either as hex, rgb, rgba, or
gradientsblend
contains a set of blend modes as CSS values that map against the
colors/integration
in the root of the project to hold integration
configuration./integration/templates
directory./integration/sass
and modified to match the new structure.This release fixes two small bugs, one that throws an error on builds because of a missing type declaration in the config.
This release creates base foundation tokens in the /exported directory. This is a major step forward allowing projects to use color, typography and effects as named tokens in projects in addition to component tokens.
This release fixes a small typo in the installer. The version in the installed package version was set to ^0.1.0 rather than ^0.2.0. This release fixes that.
```{type}
to define the syntax. For example ```js
.