This release is a major reorganization of Handoff. We've preserved the core Figma Token ETL behavior, but this release significantly rethinks and improves the documentation application.
This is a significant breaking change. We recommend starting from a fresh project. Its possible to upgrade an existing Handoff project, but its easier to start fresh. Previous versions of handoff depended on specific structure. We're working to remove any structure or conventions, so you can use handoff in any project as you see fit.
Contact us if you need help upgrading a legacy project handoff@convertiv.com.
Justification
The Handoff documentation app was initial designed to complement the token extraction and document simple tokens. Over time, we added the ability to document Figma components in the application. We supported integrations that would allow users to describe Figma components in code.
As we built out more complex design system documentation, we quickly hit the limits of what we could build and describe with that simple system. We needed a way to flexibly describe components - both defined in Figma, and standalone custom components. There are other open source products like Storybook that have some of this functionality but we were looking for a more flexible, and robust architecture for describing and distributing components across ecosystems.
This release does a number major things -
- Introduces a new component architecture, allowing users to describe components using handlebars, css, and JSON
- These components are built, compiled, and validated on each handoff build. The build system is designed to be highly configurable.
- Each component has a set of typed properties allowing users to pass pass in data to the component, and visualize variations
- Components can be annotated with metadata to allow users to provide robust usage guidelines.
- Each component is semver versioned
- Publishes a robust API at /api/components.json that allows remote systems to query the component structure
- Each component is published at /api/component/{name}.json. This allows systems to fetch just the relevant component.
- Completely redesigns and rearchitects the application.
- Redesigned using shadCn tailwind components
- Reorganized the information architecture to default to best practice in organizing foundations, systems and guidelines.
- This architecture and design can be customized
See the demo site at demo.handoff.com and the demo code at https://demo.handoff.com and the code at https://github.com/Convertiv/handoff-demo to have a sample of how this should be structured
Component Structure
In this version components should be stored at {integrationPath}/components
. Each integration should be in a folder with a unique name. This name will be used as the id for the component.
Within each component folder, there should be at least one folder, named with a semver name. The structure of this should look like
- {integrationPath}
- components
- component1
- 1.0.0
- component1.json - Describes the component in a JSON format documented below
- component1.hbs - A handlebar template to describe the markup of the component
- component1.scss - An optional style sheet to include with the project
- component1.js - An optional js file to include with the project
- 1.0.0
- component1
- components
Minimum Component JSON
This is a sample json component to show how you can structure the component documentation. Most of this is metadata used to construct robust documentation for users.
The two important semantic sections are previews
and properties
. Properties defines a list of properties the component accepts. They are defined using the OpenAPI json specification.
Once you define a list of properties, you can then define a list of previews. Each preview defines values for the properties. Handoff will then render a set of html previews of your component. This way you can render variations simply.
{
"title": "Accordion",
"image": "https://placehold.co/1360x900",
"description": "Collapsible sections for toggling sections of content on and off.",
"figma": "https://www.figma.com/design/0gKWw8gYChpItKWzh8o23N/SS%26C-Design-System?node-id=301-598&t=qoaWE7Tx8sH4njGu-4",
"type": "block",
"group": "Accordion",
"categories": ["Components"],
"tags": ["accordion"],
"should_do": ["Show a list of items in an accordion format.", "Allow users to expand and collapse each item individually."],
"should_not_do": ["Use this component for a large number of items."],
"changelog": [
{
"version": "1.0.0",
"date": "2021-01-01",
"changes": ["Initial version."]
}
],
"previews": {
"generic": {
"title": "Generic",
"values": {
"id": "accordion",
"items": [
{
"id": "accordion-item-1",
"title": "Accordion Item 1",
"paragraph": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.",
"image": {
"url": "https://placehold.co/1360x900",
"alt": "Image alt text"
}
},
}
]
}
}
},
"properties": {
"id": {
"name": "ID",
"description": "Unique identifier for the accordion.",
"type": "text",
"default": "accordion",
"rules": {
"required": true,
"content": {
"min": 5,
"max": 25
},
"pattern": "^[a-z0-9-]+$"
}
},
"items": {
"name": "Items",
"description": "Accordion items",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"name": "ID",
"description": "Unique identifier for the accordion item.",
"type": "text",
"default": "accordion-item-1",
"rules": {
"required": true,
"content": {
"min": 5,
"max": 25
},
"pattern": "^[a-z0-9-]+$"
}
},
"title": {
"name": "Title",
"description": "Title of the accordion item.",
"type": "text",
"default": "Accordion Item 1",
"rules": {
"required": true,
"content": {
"min": 5,
"max": 25
}
}
},
"paragraph": {
"name": "Paragraph",
"description": "Paragraph of the accordion item.",
"type": "text",
"default": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.",
"rules": {
"required": true,
"content": {
"min": 5,
"max": 100
}
}
},
"image": {
"name": "Image",
"description": "Image of the accordion item.",
"type": "image",
"default": {
"url": "https://placehold.co/1360x900",
"alt": "Image alt text"
},
"rules": {
"required": true,
"dimensions": {
"min": {
"width": 1360,
"height": 900
},
"max": {
"width": 1360,
"height": 900
}
}
}
}
}
},
"rules": {
"required": true,
"min": 1,
"max": 10
}
}
}
}
Handlebars Templates
We anticipate allowing other templating systems in the future, but in this
version, we support handlebars with limited logic. Using Handlebars allows
us to create a simple system that will be compatible with most downstream
platforms.
There are two special feature of this handlebars file -
#field
This allows you wrap a field in a tag. This allows Handoff to inject
metadata around a field to make the field inline editable, and to allow us to
open a sidebar with metadata about the property. You don't have to use this
but its helpful.style
andscript
- These tags allow us to inject automatically the built
script and style artifacts.
<head>
{{{style}}} {{{script}}}
</head>
<body class="preview-body">
<section class="py-lg-12 py-8">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-lg-10">
<div class="accordion accordion-spaced" id="{{properties.id}}">
{{#each properties.items}}
<div class="accordion-item">
<h3 class="accordion-header" id="{{../properties.id}}-heading-{{this.id}}">
<button
class="accordion-button"
type="button"
data-bs-toggle="collapse"
data-bs-target="#{{../properties.id}}-collapse-{{this.id}}"
aria-expanded="true"
aria-controls="{{../properties.id}}-collapse-{{this.id}}"
>
{{#field "items.title" }}{{this.title}}{{/field}}
</button>
</h3>
<div
id="{{../properties.id}}-collapse-{{this.id}}"
class="accordion-collapse collapse"
aria-labelledby="{{this.id}}"
data-bs-parent="#{{../properties.id}}-heading-{{this.id}}"
>
<div class="accordion-body w-lg-90 mx-lg-auto fs-lg">
<p>{{#field "items.paragraph" }}{{this.paragraph}}{{/field}}</p>
</div>
</div>
</div>
{{/each}}
</div>
</div>
</div>
</div>
</section>
</body>
Changes
- Prerelease cleanup 6e39404
- Pre 0.16 release build 3130f4d
- Merge pull request #179 from Convertiv/release/0.16.0 640ec67
- Merge branch 'release/0.16.0' of github.com:Convertiv/handoff-app into release/0.16.0 c5497f0
- Extending docs 603b099
- Merge pull request #178 from Convertiv/feature/update-transformed-mdx-import-paths 7462039
- Update transformed mdx import paths. bd8616d
- Adding notes 8277c3c
- Documenting 0.16 release 0a7a44a
- Merge branch 'feature/doc-site-integration' into release/0.16.0 7b0e88c
- Homepage mobile spacing updates. 7556678
- Added mobile nav. 4001a7a
- Modified the homepage to be responsive. ed19ac5
- Added blocks and components illustrations. 8294f60
- Added blocks illustration, removed component toolbar on mobile. 3839e88
- Merge branch 'feature/doc-site-integration' into release/0.16.0 c3b4f4c
- Moving tailwind containers into deps to allow them to be used in child projects c01b893
- Updating depedencies 33caebf
- Merge branch 'feature/doc-site-integration' into feautre/doc-site-integration-configuration bf881c7
- Merge branch 'feature/doc-site-integration' of github.com:Convertiv/handoff-app into feature/doc-site-integration ae19fcf
- Adding color ratio algorithm 3d42716
- Initial implementation of hot reloading functionality for components. 7938164
- Don't validate configuration for dev, start and build 4f4b64f
- Merge branch 'feature/doc-site-integration' of github.com:Convertiv/handoff-app into feature/doc-site-integration afa8e90
- Adding todo: in folder export check for validate config 448c997
- Linking home page eb59b2b
- Merge branch 'feature/doc-site-integration' into feautre/doc-site-integration-configuration 94d9a6e
- Merge pull request #174 from Convertiv/feature/active-state-for-nav-menu-items 6817935
- Merge branch 'feature/doc-site-integration' into feautre/doc-site-integration-configuration 1c91e4c
- Merge branch 'feautre/doc-site-integration-configuration' of github.com:Convertiv/handoff-app into feautre/doc-site-integration-configuration 31fadc7
- Homepage changes. 95d8e23
- Enable easier definition of component entries by providing path(s) to component collection directory instead of having to specify individual components. Retain support for individual paths. Improve handling of cases when component cannot be loaded. 9d9323f
- Icons copy update, icon single page update. 46868ba
- Merge branch 'feature/doc-site-integration' into feautre/doc-site-integration-configuration d5921d0
- Changed icon library to container query. 11876c4
- Removed header main nav on tablet size. 51075f3
- Fixed typography page responsive view. e46f48c
- Fixed container queries. 53dc964
- build 0a1194a
- Merge branch 'feature/doc-site-integration' into feautre/doc-site-integration-configuration 1a038e8
- Logging. afa1537
- Use component basename as the component id 6e4b349
- Link logo to home page 6bb9a62
- Implemented (better) handling of config file changes. 329bcd8
- Fixing race condition generating the component api 7e25e41
- Trying to debug race condition 96b02cc
- Fixing button issue 9a49512
- Making deprecation warnings less loud until we provide a way for users to customize this 046f546
- Mobile view improvements. fee5cb8
- Icons page, multiple layout adjustments. 164b233
- Adding header 93317cf
- Removing old header 001a3a6
- Fixing path bug 330e8cf
- Removing old components c6b4a48
- Adding temp theme.css file 9470927
- Merge branch 'feature/doc-site-integration' into feautre/doc-site-integration-configuration 5bcb42c
- Fixing problem with sass build f4a00bb
- Introduced support for active menu item state for all menu items. d006989
- Merge pull request #173 from Convertiv/feature/tailwind-configuration-improvements 72135a5
- Tailwind configuration improvements. Removed need for having tailwind config file in the root of the project using handoff. e862120
- Better handling of cases when existing file cannot be parsed. 5b5fcdc
- Build bugfix. Removed call to a non-existing function. c195c5c
- Handle no entries for component. 599a6d0
- Improvements. ebf9b1a
- Entries config support for main integration and components. 4fbb60e
- Ensure component transformer waits for component main js/css 3cfbf0e
- `Merge branch 'feature/doc-site-integration' of github.com:Convertiv/handoff-app into feature/doc-site-integration c028037
- adding integration style command a1c7c04
- build css bug 5a6c76a
- Adding temp css builder 21c3225
- Fixing case where data is string b9a48fa
- Fixing build problem a16becb
- Merge branch 'feature/doc-site-integration' of github.com:Convertiv/handoff-app into feature/doc-site-integration 928f7ff
- Resolved CodeHighlight missing code issue. 29c8a58
- Fixing small bug in preview 623d16d
TRUNCATED...