Each component has a set of previews and code snippets for the states and types of the component. Templates are how you can customize those previews and accompanying code snippets.
When you create a new handoff project, the installer creates a templates
folder. That folder has this structure -
1templates/ 2├── .gitkeep 3├── button 4│ └── default.html 5├── main.js 6├── main.scss 7├── preview.scss 8└── readme.md
These files will allow you to customize the component previews and code snippets. Each component has its own set of templates that can be customized. Some like buttons can be customized per type (primary, secondary, etc.). Others, like inputs can be customized by their state (default, error, disabled, etc).
For a full list of components you can customize, see here - https://github.com/Convertiv/handoff-app/blob/main/templates/
To customize a template, you should create a folder in the templates directory
that corresponds with the name of the component you want to customize. So for
inputs, create a folder called input
.
To customize the default input preview, create a file called default.html
in
the input folder. These files are
mustache templates. In a template you can access
any variable for the component out of the tokens.json
. So in the example below
you will see we can pull the label from Figma by fetching
{{parts.label.characters}}
.
Your custom input html will look like this -
1<script src="/components/bundle.js"></script> 2 3<body class="theme-{{ theme }} input flex-column"> 4 <div class="mb-3"> 5 <label class="form-label" for="formText">{{parts.label.characters}}</label> 6 <input 7 type="text" 8 class="form-control" 9 id="formText" 10 placeholder="{{parts.text.characters}}" 11 /> 12 <div class="form-text">{{parts.additionalInfo.characters}}</div> 13 </div> 14</body>
Handoff creates previews by merging these templates with the Figma tokens. These generated previews are then iFramed into so they are fully functional previews. By iFraming the previews, we can isolate them from the parent styling, ensuring that each component displays perfectly, and not inherit styles from the main site.
Each template loads a CSS and JS bundle. This allows you to add base styles, JS behaviors, and include all of the tokens generated by Handoff. If you are using a framework like bootstrap or tailwinds, you can install the version via NPM, and add it using an ES6 import here.
To customize the styles of a preview, edit templates/main.css
and add the
styles that you want. For instance, you can add a custom google font to the
preview by adding this to templates/main.css
1@import url("https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Serif:ital,opsz,wght@0,8..144,300;0,8..144,400;0,8..144,500;0,8..144,600;1,8..144,300;1,8..144,400;1,8..144,500;1,8..144,600&display=swap"); 2font-family: "Roboto", sans-serif; 3font-family: "Roboto Serif", serif;
To add custom JS behaviors to your buttons, use NPM to install whatever js libraries you want. All bootstrap libraries are already available. Then you can use them as normal.
1import { Tooltip } from "bootstrap"; 2import "iframe-resizer/js/iframeResizer.contentWindow"; 3// bootstrap css 4import "./main.scss"; 5import "./preview.scss"; 6 7// enable tooltips 8document.addEventListener("DOMContentLoaded", function (event) { 9 const tooltipTriggerList = document.querySelectorAll( 10 '[data-bs-toggle="tooltip"]' 11 ); 12 const tooltipList = [...tooltipTriggerList].map( 13 (tooltipTriggerEl) => 14 new Tooltip(tooltipTriggerEl, { 15 boundary: document.body, 16 }) 17 ); 18});