handoff-app 0.13.0 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +99 -78
- package/dist/app.js +9 -3
- package/dist/cli/eject.js +20 -11
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/pipeline.js +4 -1
- package/dist/transformers/integration/index.js +8 -5
- package/dist/utils/preview.js +10 -4
- package/package.json +1 -1
- package/src/app/components/AnchorNavLink.tsx +17 -6
- package/src/app/components/ComponentDesignTokens.tsx +1 -1
- package/src/app/pages/_app.tsx +1 -1
- package/src/app.ts +4 -0
- package/src/cli/eject.ts +4 -2
- package/src/cli.ts +1 -1
- package/src/index.ts +2 -1
- package/src/pipeline.ts +3 -1
- package/src/transformers/integration/index.ts +24 -7
- package/src/utils/preview.ts +8 -4
package/Changelog.md
CHANGED
|
@@ -6,11 +6,32 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to
|
|
7
7
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [0.13.2] - 2024-09-18
|
|
10
|
+
|
|
11
|
+
This release addresses several developer experience issues
|
|
12
|
+
|
|
13
|
+
### Bugfixes
|
|
14
|
+
|
|
15
|
+
- When an integration compiles SASS code, the token injection was injecting components that had no instances in Figma. This causes integrations to fail if the designer had published a component, but not annotated them in Figma with the plugin. This release checks to see if the component has any instances in the Figma export and skips injection for components that are not yet annotated in Figma
|
|
16
|
+
- When running `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 app
|
|
17
|
+
- If an an `build: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.
|
|
18
|
+
- When ejecting an integration with the `--force` flag, the force now triggers an overwrite rather than failing.
|
|
19
|
+
|
|
20
|
+
## [0.13.1] - 2024-09-17
|
|
21
|
+
|
|
22
|
+
This release fixes a couple of small path issues that affect running 0.13.0 from the global path.
|
|
23
|
+
|
|
24
|
+
### Bugfixes
|
|
25
|
+
|
|
26
|
+
- Fix a path issue in the ComponentDesignTokens component that causes an error when run from the global namespace
|
|
27
|
+
- Prevents typescript compile errors with the react-scroll `<Link>` component
|
|
28
|
+
|
|
9
29
|
## [0.13.0] - 2024-09-08
|
|
10
30
|
|
|
11
31
|
### Changes
|
|
12
32
|
|
|
13
33
|
- **Integration System Overhaul**
|
|
34
|
+
|
|
14
35
|
- **Local Integrations Only:** From this release onward, only local (ejected) integrations are supported. Handoff will automatically use the locally found integration.
|
|
15
36
|
- Create a new local integration using `handoff-app make:integration` (or `eject:integration` which is still supported as an alias).
|
|
16
37
|
- Since there is no need to specify integration information, integration options in `handoff.config.json` such as name and version are no longer recognized, making the integration section of `handoff.config.json` obsolete.
|
|
@@ -40,11 +61,11 @@ and this project adheres to
|
|
|
40
61
|
- **For Projects with Legacy Schemas:**
|
|
41
62
|
1. Eject legacy schemas using `handoff-app eject:exportables`.
|
|
42
63
|
2. If schemas are already ejected:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
64
|
+
- Verify that transformer options are in `integration.config.json`.
|
|
65
|
+
- Verify that demo options are in `view.config.json` files of respective components.
|
|
66
|
+
- Temporarily rename the directory containing legacy schemas.
|
|
67
|
+
- Re-eject schemas and move custom schemas into the new exportables.
|
|
68
|
+
- Optionally, update custom schemas to remove obsolete options.
|
|
48
69
|
- **For Projects with `handoff.config.json`:**
|
|
49
70
|
1. Merge options from `figma.options` to the `integration.config.json` file as necessary.
|
|
50
71
|
2. Optionally remove deprecated sections: `figma.options`, `figma.definitions`, `figma`, `integration`, and `use_legacy_definitions`.
|
|
@@ -53,122 +74,122 @@ and this project adheres to
|
|
|
53
74
|
|
|
54
75
|
### Changes
|
|
55
76
|
|
|
56
|
-
|
|
77
|
+
- Integration bundle used for the docs app is no longer being built during `fetch` and `build:integration` steps.
|
|
57
78
|
|
|
58
79
|
## [0.12.1] - 2024-06-18
|
|
59
80
|
|
|
60
81
|
### Changes
|
|
61
82
|
|
|
62
|
-
|
|
83
|
+
- Added support for the `cssRootClass` property in the Handoff Figma plugin metadata.
|
|
63
84
|
|
|
64
85
|
### Improvements
|
|
65
86
|
|
|
66
|
-
|
|
87
|
+
- Enhanced handling of unnamed parts, resolving visibility issues in the documentation previews.
|
|
67
88
|
|
|
68
89
|
## [0.12.0] - 2024-06-11
|
|
69
90
|
|
|
70
91
|
### Changes
|
|
71
92
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
- All environment variables now contain the `HANDOFF_` prefix.
|
|
94
|
+
- After updating to version 0.12.0, all environment variables need to be updated to reflect the new variable names:
|
|
95
|
+
- `FIGMA_BASE_URL` -> `HANDOFF_FIGMA_BASE_URL`
|
|
96
|
+
- `DEV_ACCESS_TOKEN` -> `HANDOFF_DEV_ACCESS_TOKEN`
|
|
97
|
+
- `FIGMA_PROJECT_ID` -> `HANDOFF_FIGMA_PROJECT_ID`
|
|
98
|
+
- `OUTPUT_DIR` -> `HANDOFF_OUTPUT_DIR`
|
|
99
|
+
- `SITES_DIR` -> `HANDOFF_SITES_DIR`
|
|
100
|
+
- `USE_HANDOFF_PLUGIN` -> `HANDOFF_USE_HANDOFF_PLUGIN`
|
|
101
|
+
- `CREATE_ASSETS_ZIP_FILES` -> `HANDOFF_CREATE_ASSETS_ZIP_FILES`
|
|
102
|
+
- The default integration is no longer pre-defined.
|
|
103
|
+
- Bootstrap 5.3 is no longer set as the default integration.
|
|
104
|
+
- To continue using the Bootstrap 5.3 integration in your project, ensure the configuration is ejected (`handoff-app eject:config`) and update it by setting the `integration` property to `{name: 'bootstrap', version: '5.3'}`.
|
|
105
|
+
- All default options specified in the configuration that are used by the exporter and transformer have been removed.
|
|
106
|
+
- To continue using the defaults present before the 0.12.0 release, ensure the configuration is ejected (`handoff-app eject:config`) and update the `figma.options` property to the [previous default value](https://github.com/Convertiv/handoff-app/blob/2a396145e7366732ae6a0e15cdf2226641d40a12/src/config.ts#L36-L59).
|
|
107
|
+
- The logo placeholder copy showing spacing and orientation has been removed allowing users to add custom content via Markdown.
|
|
87
108
|
|
|
88
109
|
### Improvements
|
|
89
110
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
111
|
+
- Handoff now appends to existing `.env` files instead of overriding them if the file already exists.
|
|
112
|
+
- Introduced normalization of numeric values in `.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.
|
|
113
|
+
- Configuration ejected by the `handoff-app eject:integration` command is now the same as the one ejected by the `handoff-app eject:config` command.
|
|
114
|
+
- Handoff no longer uses the `iframe-resizer` package.
|
|
115
|
+
- Resolved potential security issues by updating to newer versions of the `axios` and `next` packages.
|
|
95
116
|
|
|
96
117
|
## [0.11.0] - 2024-05-23
|
|
97
118
|
|
|
98
119
|
### Bugfixes
|
|
99
120
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
121
|
+
- Issue that was causing the `handoff-app start` command to malfunction has been fixed.
|
|
122
|
+
- The `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.
|
|
123
|
+
- Icon sizes have been corrected.
|
|
103
124
|
|
|
104
125
|
### Changes
|
|
105
126
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
127
|
+
- **Integration with Handoff Figma Plugin**: This release now seamlessly integrates with the Handoff Figma Plugin by default.
|
|
128
|
+
- As a result, the local schema will not be used by default.
|
|
129
|
+
- If you prefer to continue using local schemas, set `USE_HANDOFF_PLUGIN="FALSE"` in your `.env` file.
|
|
130
|
+
- Internal module working directory has been relocated from `./src` to `./.handoff`
|
|
110
131
|
|
|
111
132
|
## [0.10.0] - 2024-01-16
|
|
112
133
|
|
|
113
134
|
### Improvements
|
|
114
135
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
136
|
+
- Docs App:
|
|
137
|
+
- Updated docs app to present components without associated content and assets more elegantly.
|
|
138
|
+
- Improved the component pages by showing only the "Tokens" tab when no previews are detected; the "Overview" tab is hidden in such cases.
|
|
139
|
+
- Configuration Handling:
|
|
140
|
+
- Eliminated the need for `handoff.state.json` file.
|
|
141
|
+
- All required parameters are now passed to the docs app through environment variables (`process.env`), defined in the project's respective `next.config.js` file.
|
|
142
|
+
- Replaced `getConfig` with the more secure `getClientConfig` function.
|
|
143
|
+
- New function returns only configurations that can be safely exposed on the client side.
|
|
123
144
|
|
|
124
145
|
### Changes
|
|
125
146
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
- Handoff Figma Plugin Support:
|
|
148
|
+
- Introduced initial support for the Handoff Figma Plugin.
|
|
149
|
+
- Currently an opt-in feature as development is ongoing.
|
|
150
|
+
- Can be enabled by setting `USE_HANDOFF_PLUGIN="TRUE"` in your `.env` file.
|
|
151
|
+
- This functionality allows Handoff to extract metadata directly from the Figma file. Local JSON definitions are completely ignored in this case.
|
|
152
|
+
- Will become the default behavior in the 1.0.0 release!
|
|
153
|
+
- Deprecation Notice:
|
|
154
|
+
- Deprecated local exportable component JSON definitions.
|
|
155
|
+
- Still usable, but will be completely removed and ignored before the 1.0.0 release.
|
|
156
|
+
- Components, parts, and related definitions should be defined with the Handoff Figma Plugin prior to the 1.0.0 release.
|
|
136
157
|
|
|
137
158
|
## [0.9.3] - 2023-11-23
|
|
138
159
|
|
|
139
160
|
### Improvements
|
|
140
161
|
|
|
141
|
-
|
|
142
|
-
|
|
162
|
+
- It's now possible to declare conditions for exportable component parts. Condition dictates should the part be built based on provided condition (e.g. does a specific variant property have a certain value etc.).
|
|
163
|
+
- Handoff will now process all component sets found within the frame in which the component set that matches the search is found. Previously it was limited to process only one (first) extra component set while others were ignored.
|
|
143
164
|
|
|
144
165
|
### Changes
|
|
145
166
|
|
|
146
|
-
|
|
167
|
+
- Component preview title will no longer default to the value of the first variant property if no distinctive value is found. Empty value is now used instead.
|
|
147
168
|
|
|
148
169
|
### Bugfixes
|
|
149
170
|
|
|
150
|
-
|
|
151
|
-
|
|
171
|
+
- Update of the app source will now update the watched app without having to restart the watch process (issue introduced in version 0.9.0).
|
|
152
172
|
|
|
153
173
|
## [0.9.2] - 2023-11-21
|
|
154
174
|
|
|
155
175
|
### Improvements
|
|
156
176
|
|
|
157
|
-
|
|
177
|
+
- Handoff now supports both **personal access** and **OAuth2 bearer** tokens. If Handoff detects that a access token used starts with "Bearer " it will use the `Authorization` header to send the token as part of any Figma API request. In any other case, `X-Figma-Token` header will be used.
|
|
158
178
|
|
|
159
179
|
## [0.9.1] - 2023-11-14
|
|
160
180
|
|
|
161
181
|
### Changes
|
|
162
182
|
|
|
163
|
-
|
|
164
|
-
|
|
183
|
+
- Footer component has been brought back into the app and is now visible on all pages.
|
|
184
|
+
- Introduced token maps export feature which exports generated tokens alongside their respective values in form in JSON files (key/value object). Tokens for individual components/foundations are exported into the `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.
|
|
165
185
|
|
|
166
186
|
### Improvements
|
|
167
|
-
|
|
187
|
+
|
|
188
|
+
- Added additional logging into the app's `next.config.js` file alongside improved path resolving for custom themes.
|
|
168
189
|
|
|
169
190
|
### Maintenance
|
|
170
191
|
|
|
171
|
-
|
|
192
|
+
- Updated the `.npmignore` file to reflect latest `.gitignore` changes made in the last release.
|
|
172
193
|
|
|
173
194
|
## [0.9.0] - 2023-11-10
|
|
174
195
|
|
|
@@ -176,27 +197,27 @@ This release focuses heavily on better support for environments on which multipl
|
|
|
176
197
|
|
|
177
198
|
### Changes
|
|
178
199
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
200
|
+
- Handoff exports and builds are now updated to support export and build of multiple projects. Each respective output is now located in the subdirectory that matches the exported project id (e.g. /exports/{figmaProjectId}). This change prevents issues where one project would override handoff output of another project in environments where multiple Figma projects are being handled.
|
|
201
|
+
- Due to the change in the output directory structure, Bootstrap integration has been updated with a @exported alias which is set to point to export directory of the current project for which the integration is being built.
|
|
202
|
+
- Alongside existing support for customized app assets via the `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.
|
|
203
|
+
- Handoff state file now always includes the Figma project id.
|
|
204
|
+
- Initial anonymization of the config file that gets loaded into the app to prevent secrets from being exposed on the client side.
|
|
205
|
+
- Improvements to path resolving for custom app theme(s).
|
|
206
|
+
- Restructure and improvements of the configuration:
|
|
207
|
+
- `poweredBy` option is now called `attribution` and has been moved into `app` config key.
|
|
208
|
+
- `next_base_path` option is now called `base_path` and has been moved into the `app` config key.
|
|
209
|
+
- Following options have also been moved into the `app` config key: `theme`, `title`, `client`, `google_tag_manager`, `type_copy`, `type_sort`, `color_sort`, `component_sort`
|
|
210
|
+
- `logo` and `favicon` options have been removed (it’s still possible to use custom assets but their name must match the default names).
|
|
211
|
+
- Misc.
|
|
191
212
|
|
|
192
213
|
### Bugfixes
|
|
193
214
|
|
|
194
|
-
|
|
215
|
+
- Resolved the wrong favicon path issue when app base path was set/used.
|
|
195
216
|
|
|
196
217
|
### Migrate to a New Version
|
|
197
218
|
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
- Due to the restructure of the configuration, any local configuration (if exists) needs to be updated to match the new structure. Recommended way is to create a backup of the current local configuration(s) and to re-eject of the handoff configuration. Use the backup of the local configuration to update the up-to-date configuration ejected earlier. This process will ensure all the configuration options are defined correctly.
|
|
220
|
+
- Since the export and app output directory structures have been updated, any custom script that relies on the old output path(s) should be updated to support new structure that includes the project id subdirectory.
|
|
200
221
|
|
|
201
222
|
## [0.8.8] - 2023-10-19
|
|
202
223
|
|
package/dist/app.js
CHANGED
|
@@ -61,6 +61,7 @@ var fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
61
61
|
var chokidar_1 = __importDefault(require("chokidar"));
|
|
62
62
|
var chalk_1 = __importDefault(require("chalk"));
|
|
63
63
|
var preview_1 = require("./utils/preview");
|
|
64
|
+
var pipeline_1 = require("./pipeline");
|
|
64
65
|
var getWorkingPublicPath = function (handoff) {
|
|
65
66
|
var paths = [
|
|
66
67
|
path_1.default.resolve(handoff.workingPath, "public-".concat(handoff.config.figma_project_id)),
|
|
@@ -147,17 +148,22 @@ var buildApp = function (handoff) { return __awaiter(void 0, void 0, void 0, fun
|
|
|
147
148
|
if (!fs_extra_1.default.existsSync(path_1.default.resolve(handoff.workingPath, handoff.exportsDirectory, handoff.config.figma_project_id, 'tokens.json'))) {
|
|
148
149
|
throw new Error('Tokens not exported. Run `handoff-app fetch` first.');
|
|
149
150
|
}
|
|
151
|
+
// If we are building the app, ensure the integration is built first
|
|
152
|
+
return [4 /*yield*/, (0, pipeline_1.buildIntegrationOnly)(handoff)];
|
|
153
|
+
case 1:
|
|
154
|
+
// If we are building the app, ensure the integration is built first
|
|
155
|
+
_a.sent();
|
|
150
156
|
// Build client preview styles
|
|
151
157
|
return [4 /*yield*/, (0, preview_1.buildClientFiles)(handoff)
|
|
152
158
|
.then(function (value) { return !!value && console.log(chalk_1.default.green(value)); })
|
|
153
159
|
.catch(function (error) {
|
|
154
160
|
throw new Error(error);
|
|
155
161
|
})];
|
|
156
|
-
case
|
|
162
|
+
case 2:
|
|
157
163
|
// Build client preview styles
|
|
158
164
|
_a.sent();
|
|
159
165
|
return [4 /*yield*/, prepareProjectApp(handoff)];
|
|
160
|
-
case
|
|
166
|
+
case 3:
|
|
161
167
|
appPath = _a.sent();
|
|
162
168
|
// Build app
|
|
163
169
|
return [4 /*yield*/, (0, next_build_1.nextBuild)({
|
|
@@ -168,7 +174,7 @@ var buildApp = function (handoff) { return __awaiter(void 0, void 0, void 0, fun
|
|
|
168
174
|
experimentalTurbo: false,
|
|
169
175
|
experimentalBuildMode: 'default',
|
|
170
176
|
}, appPath)];
|
|
171
|
-
case
|
|
177
|
+
case 4:
|
|
172
178
|
// Build app
|
|
173
179
|
_a.sent();
|
|
174
180
|
outputRoot = path_1.default.resolve(handoff.workingPath, handoff.sitesDirectory);
|
package/dist/cli/eject.js
CHANGED
|
@@ -45,6 +45,7 @@ var fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
45
45
|
var chalk_1 = __importDefault(require("chalk"));
|
|
46
46
|
var integration_1 = require("../transformers/integration");
|
|
47
47
|
var config_1 = require("../config");
|
|
48
|
+
var pipeline_1 = require("../pipeline");
|
|
48
49
|
/**
|
|
49
50
|
* Eject the config to the working directory
|
|
50
51
|
* @param handoff
|
|
@@ -72,18 +73,26 @@ exports.ejectConfig = ejectConfig;
|
|
|
72
73
|
var makeIntegration = function (handoff) { return __awaiter(void 0, void 0, void 0, function () {
|
|
73
74
|
var config, workingPath, integrationPath;
|
|
74
75
|
return __generator(this, function (_a) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
switch (_a.label) {
|
|
77
|
+
case 0:
|
|
78
|
+
config = handoff.config;
|
|
79
|
+
workingPath = path_1.default.resolve(path_1.default.join(handoff.workingPath, 'integration'));
|
|
80
|
+
if (fs_extra_1.default.existsSync(workingPath)) {
|
|
81
|
+
if (!handoff.force) {
|
|
82
|
+
console.log(chalk_1.default.red("An integration already exists in the working directory. Use the --force flag to overwrite."));
|
|
83
|
+
return [2 /*return*/];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
integrationPath = (0, integration_1.getPathToIntegration)(handoff, true);
|
|
87
|
+
fs_extra_1.default.copySync(integrationPath, workingPath, { overwrite: handoff.force ? true : false });
|
|
88
|
+
if (handoff.force)
|
|
89
|
+
handoff.force = false;
|
|
90
|
+
return [4 /*yield*/, (0, pipeline_1.buildIntegrationOnly)(handoff)];
|
|
91
|
+
case 1:
|
|
92
|
+
_a.sent();
|
|
93
|
+
console.log(chalk_1.default.green("Integration has been successfully created! Path: ".concat(workingPath)));
|
|
94
|
+
return [2 /*return*/, handoff];
|
|
82
95
|
}
|
|
83
|
-
integrationPath = (0, integration_1.getPathToIntegration)(handoff, true);
|
|
84
|
-
fs_extra_1.default.copySync(integrationPath, workingPath, { overwrite: false });
|
|
85
|
-
console.log(chalk_1.default.green("Integration has been successfully created! Path: ".concat(workingPath)));
|
|
86
|
-
return [2 /*return*/, handoff];
|
|
87
96
|
});
|
|
88
97
|
}); };
|
|
89
98
|
exports.makeIntegration = makeIntegration;
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -56,4 +56,5 @@ declare class Handoff {
|
|
|
56
56
|
postIntegration(callback: (documentationObject: DocumentationObject, data: HookReturn[]) => HookReturn[]): void;
|
|
57
57
|
modifyWebpackConfig(callback: (webpackConfig: webpack.Configuration) => webpack.Configuration): void;
|
|
58
58
|
}
|
|
59
|
+
export declare const initIntegrationObject: (workingPath: string) => IntegrationObject;
|
|
59
60
|
export default Handoff;
|
package/dist/index.js
CHANGED
|
@@ -73,6 +73,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
73
73
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
74
74
|
};
|
|
75
75
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
76
|
+
exports.initIntegrationObject = void 0;
|
|
76
77
|
var config_1 = require("./config");
|
|
77
78
|
var fs_extra_1 = __importDefault(require("fs-extra"));
|
|
78
79
|
var path_1 = __importDefault(require("path"));
|
|
@@ -117,7 +118,7 @@ var Handoff = /** @class */ (function () {
|
|
|
117
118
|
this.config = this.hooks.init(this.config);
|
|
118
119
|
this.exportsDirectory = (_a = config.exportsOutputDirectory) !== null && _a !== void 0 ? _a : this.exportsDirectory;
|
|
119
120
|
this.sitesDirectory = (_b = config.sitesOutputDirectory) !== null && _b !== void 0 ? _b : this.exportsDirectory;
|
|
120
|
-
this.integrationObject = initIntegrationObject(this.workingPath);
|
|
121
|
+
this.integrationObject = (0, exports.initIntegrationObject)(this.workingPath);
|
|
121
122
|
return this;
|
|
122
123
|
};
|
|
123
124
|
Handoff.prototype.preRunner = function (validate) {
|
|
@@ -414,6 +415,7 @@ var initIntegrationObject = function (workingPath) {
|
|
|
414
415
|
var integration = JSON.parse(buffer.toString());
|
|
415
416
|
return (0, integration_2.prepareIntegrationObject)(integration, integrationPath);
|
|
416
417
|
};
|
|
418
|
+
exports.initIntegrationObject = initIntegrationObject;
|
|
417
419
|
var validateConfig = function (config) {
|
|
418
420
|
if (!config.figma_project_id && !process.env.HANDOFF_FIGMA_PROJECT_ID) {
|
|
419
421
|
// check to see if we can get this from the env
|
package/dist/pipeline.js
CHANGED
|
@@ -88,6 +88,7 @@ var index_3 = __importStar(require("./transformers/integration/index"));
|
|
|
88
88
|
var index_4 = __importDefault(require("./transformers/font/index"));
|
|
89
89
|
var index_5 = __importDefault(require("./transformers/preview/index"));
|
|
90
90
|
var app_1 = __importDefault(require("./app"));
|
|
91
|
+
var _1 = require(".");
|
|
91
92
|
var sd_1 = __importDefault(require("./transformers/sd"));
|
|
92
93
|
var map_1 = __importDefault(require("./transformers/map"));
|
|
93
94
|
var lodash_1 = require("lodash");
|
|
@@ -433,7 +434,7 @@ var buildRecipe = function (handoff) { return __awaiter(void 0, void 0, void 0,
|
|
|
433
434
|
var match;
|
|
434
435
|
var regex = new RegExp(TOKEN_REGEX, 'g');
|
|
435
436
|
var _loop_1 = function () {
|
|
436
|
-
var
|
|
437
|
+
var _2 = match[0], __ = match[1], component = match[2], part = match[3], variants = match[4], cssProperty = match[5];
|
|
437
438
|
var componentRecord = records.components.find(function (c) { return c.name === component; });
|
|
438
439
|
if (!componentRecord) {
|
|
439
440
|
componentRecord = { name: component, common: { parts: [] }, recipes: [] };
|
|
@@ -534,6 +535,8 @@ var buildIntegrationOnly = function (handoff) { return __awaiter(void 0, void 0,
|
|
|
534
535
|
case 1:
|
|
535
536
|
documentationObject = _a.sent();
|
|
536
537
|
if (!documentationObject) return [3 /*break*/, 4];
|
|
538
|
+
// Ensure that the integration object is set if possible
|
|
539
|
+
handoff.integrationObject = (0, _1.initIntegrationObject)(handoff.workingPath);
|
|
537
540
|
return [4 /*yield*/, buildIntegration(handoff, documentationObject)];
|
|
538
541
|
case 2:
|
|
539
542
|
_a.sent();
|
|
@@ -86,9 +86,11 @@ var getPathToIntegration = function (handoff, resolveTemplatePath) {
|
|
|
86
86
|
if (!handoff) {
|
|
87
87
|
throw Error('Handoff not initialized');
|
|
88
88
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
if (!handoff.force) {
|
|
90
|
+
var integrationPath = path_1.default.resolve(path_1.default.join(handoff.workingPath, 'integration'));
|
|
91
|
+
if (fs_extra_1.default.existsSync(integrationPath)) {
|
|
92
|
+
return integrationPath;
|
|
93
|
+
}
|
|
92
94
|
}
|
|
93
95
|
if (resolveTemplatePath) {
|
|
94
96
|
return path_1.default.resolve(path_1.default.join(handoff.modulePath, 'config', 'templates', 'integration'));
|
|
@@ -184,7 +186,7 @@ var zipTokens = function (dirPath, destination) { return __awaiter(void 0, void
|
|
|
184
186
|
}); };
|
|
185
187
|
exports.zipTokens = zipTokens;
|
|
186
188
|
var buildIntegration = function (sourcePath, destPath, documentationObject, rootPath, rootReturnPath) { return __awaiter(void 0, void 0, void 0, function () {
|
|
187
|
-
var items, components, _i, items_1, item, sourceItemPath, destItemPath, stat, content, template, renderedContent;
|
|
189
|
+
var items, components, componentsWithInstances, _i, items_1, item, sourceItemPath, destItemPath, stat, content, template, renderedContent;
|
|
188
190
|
return __generator(this, function (_a) {
|
|
189
191
|
switch (_a.label) {
|
|
190
192
|
case 0:
|
|
@@ -193,6 +195,7 @@ var buildIntegration = function (sourcePath, destPath, documentationObject, root
|
|
|
193
195
|
case 1:
|
|
194
196
|
items = _a.sent();
|
|
195
197
|
components = Object.keys(documentationObject.components);
|
|
198
|
+
componentsWithInstances = components.filter(function (component) { return documentationObject.components[component].instances.length > 0; });
|
|
196
199
|
_i = 0, items_1 = items;
|
|
197
200
|
_a.label = 2;
|
|
198
201
|
case 2:
|
|
@@ -229,7 +232,7 @@ var buildIntegration = function (sourcePath, destPath, documentationObject, root
|
|
|
229
232
|
// Ensure the directory exists before writing the file
|
|
230
233
|
_a.sent();
|
|
231
234
|
// Write the rendered content to the destination path
|
|
232
|
-
return [4 /*yield*/, fs_extra_1.default.writeFile(destItemPath, replaceHandoffImportTokens(renderedContent,
|
|
235
|
+
return [4 /*yield*/, fs_extra_1.default.writeFile(destItemPath, replaceHandoffImportTokens(renderedContent, componentsWithInstances, path_1.default.parse(destItemPath).dir, rootPath, rootReturnPath !== null && rootReturnPath !== void 0 ? rootReturnPath : '../'))];
|
|
233
236
|
case 9:
|
|
234
237
|
// Write the rendered content to the destination path
|
|
235
238
|
_a.sent();
|
package/dist/utils/preview.js
CHANGED
|
@@ -137,18 +137,24 @@ var buildClientFiles = function (handoff) { return __awaiter(void 0, void 0, voi
|
|
|
137
137
|
compile.run(function (err, stats) {
|
|
138
138
|
var _a, _b;
|
|
139
139
|
if (err) {
|
|
140
|
-
var error = 'Errors encountered trying to build preview styles.\n';
|
|
140
|
+
var error = chalk_1.default.red('Errors encountered trying to build preview styles.') + '\n The integration sass expects a token that isn\'t found in your Figma component.\n';
|
|
141
141
|
if (handoff.debug) {
|
|
142
|
-
error += err.stack || err;
|
|
142
|
+
error += chalk_1.default.yellow('\n\n---------- Sass Build Error Trace ---------- \n') + err.stack || err;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
error += 'Add the --debug flag to see the full error trace\n\n';
|
|
143
146
|
}
|
|
144
147
|
return reject(error);
|
|
145
148
|
}
|
|
146
149
|
if (stats) {
|
|
147
150
|
if (stats.hasErrors()) {
|
|
148
151
|
var buildErrors = (_a = stats.compilation.errors) === null || _a === void 0 ? void 0 : _a.map(function (err) { return err.message; });
|
|
149
|
-
var error = 'Errors encountered trying to build preview styles.\n';
|
|
152
|
+
var error = chalk_1.default.red('Errors encountered trying to build preview styles.') + '\nThe integration sass expects a token that isn\'t found in your Figma component.\n';
|
|
150
153
|
if (handoff.debug) {
|
|
151
|
-
error += buildErrors;
|
|
154
|
+
error += chalk_1.default.yellow('\n\n---------- Sass Build Error Trace ---------- \n') + buildErrors;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
error += 'Add the --debug flag to see the full error trace\n\n';
|
|
152
158
|
}
|
|
153
159
|
return reject(error);
|
|
154
160
|
}
|
package/package.json
CHANGED
|
@@ -11,14 +11,25 @@ export const AnchorNavLink: React.FC<AnchorNavLinkProps> = ({ to, children }) =>
|
|
|
11
11
|
|
|
12
12
|
useEffect(() => {
|
|
13
13
|
setOffset(document.getElementById('site-header')?.clientHeight ?? 0);
|
|
14
|
-
}, [])
|
|
14
|
+
}, []);
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
<>
|
|
18
|
+
{/* @ts-ignore */}
|
|
19
|
+
<Link
|
|
20
|
+
href="#"
|
|
21
|
+
activeClass="is-selected"
|
|
22
|
+
smooth
|
|
23
|
+
spy
|
|
24
|
+
to={to}
|
|
25
|
+
offset={offset * -1.5}
|
|
26
|
+
onClick={() => {
|
|
27
|
+
history.pushState ? history.pushState(null, '', `#${to}`) : (location.hash = `#${to}`);
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
{children}
|
|
31
|
+
</Link>
|
|
32
|
+
</>
|
|
22
33
|
);
|
|
23
34
|
};
|
|
24
35
|
|
|
@@ -4,7 +4,7 @@ import React, { useEffect } from 'react';
|
|
|
4
4
|
import Icon from './Icon';
|
|
5
5
|
import { transformComponentTokensToScssVariables } from '@handoff/transformers/scss/component';
|
|
6
6
|
import { ComponentInstance } from '@handoff/exporters/components/types';
|
|
7
|
-
import { IntegrationObjectComponentOptions } from '
|
|
7
|
+
import { IntegrationObjectComponentOptions } from '@handoff/types/config';
|
|
8
8
|
|
|
9
9
|
const PropertyIconPathMap = {
|
|
10
10
|
'border-width': 'token-border-width',
|
package/src/app/pages/_app.tsx
CHANGED
package/src/app.ts
CHANGED
|
@@ -9,6 +9,7 @@ import fs from 'fs-extra';
|
|
|
9
9
|
import chokidar from 'chokidar';
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import { buildClientFiles } from './utils/preview';
|
|
12
|
+
import { buildIntegrationOnly } from './pipeline';
|
|
12
13
|
|
|
13
14
|
const getWorkingPublicPath = (handoff: Handoff): string | null => {
|
|
14
15
|
const paths = [
|
|
@@ -80,6 +81,9 @@ const buildApp = async (handoff: Handoff): Promise<void> => {
|
|
|
80
81
|
throw new Error('Tokens not exported. Run `handoff-app fetch` first.');
|
|
81
82
|
}
|
|
82
83
|
|
|
84
|
+
// If we are building the app, ensure the integration is built first
|
|
85
|
+
await buildIntegrationOnly(handoff);
|
|
86
|
+
|
|
83
87
|
// Build client preview styles
|
|
84
88
|
await buildClientFiles(handoff)
|
|
85
89
|
.then((value) => !!value && console.log(chalk.green(value)))
|
package/src/cli/eject.ts
CHANGED
|
@@ -4,6 +4,7 @@ import fs from 'fs-extra';
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { getPathToIntegration } from '../transformers/integration';
|
|
6
6
|
import { getClientConfig } from '../config';
|
|
7
|
+
import { buildIntegrationOnly } from '../pipeline';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Eject the config to the working directory
|
|
@@ -40,9 +41,10 @@ export const makeIntegration = async (handoff: Handoff) => {
|
|
|
40
41
|
|
|
41
42
|
// perform integration ejection
|
|
42
43
|
const integrationPath = getPathToIntegration(handoff, true);
|
|
43
|
-
fs.copySync(integrationPath, workingPath, { overwrite: false });
|
|
44
|
+
fs.copySync(integrationPath, workingPath, { overwrite: handoff.force ? true : false });
|
|
45
|
+
if (handoff.force) handoff.force = false;
|
|
46
|
+
await buildIntegrationOnly(handoff);
|
|
44
47
|
console.log(chalk.green(`Integration has been successfully created! Path: ${workingPath}`));
|
|
45
|
-
|
|
46
48
|
return handoff;
|
|
47
49
|
};
|
|
48
50
|
|
package/src/cli.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -219,7 +219,8 @@ const initConfig = (configOverride?: any): Config => {
|
|
|
219
219
|
return returnConfig;
|
|
220
220
|
};
|
|
221
221
|
|
|
222
|
-
|
|
222
|
+
|
|
223
|
+
export const initIntegrationObject = (workingPath: string): IntegrationObject => {
|
|
223
224
|
const integrationPath = path.join(workingPath, 'integration');
|
|
224
225
|
|
|
225
226
|
if (!fs.existsSync(integrationPath)) {
|
package/src/pipeline.ts
CHANGED
|
@@ -19,7 +19,7 @@ import integrationTransformer, { getPathToIntegration } from './transformers/int
|
|
|
19
19
|
import fontTransformer from './transformers/font/index';
|
|
20
20
|
import previewTransformer from './transformers/preview/index';
|
|
21
21
|
import buildApp from './app';
|
|
22
|
-
import Handoff from '.';
|
|
22
|
+
import Handoff, { initIntegrationObject } from '.';
|
|
23
23
|
import sdTransformer from './transformers/sd';
|
|
24
24
|
import mapTransformer from './transformers/map';
|
|
25
25
|
import { merge } from 'lodash';
|
|
@@ -429,6 +429,8 @@ export const buildRecipe = async (handoff: Handoff) => {
|
|
|
429
429
|
export const buildIntegrationOnly = async (handoff: Handoff) => {
|
|
430
430
|
const documentationObject: DocumentationObject | undefined = await readPrevJSONFile(tokensFilePath(handoff));
|
|
431
431
|
if (documentationObject) {
|
|
432
|
+
// Ensure that the integration object is set if possible
|
|
433
|
+
handoff.integrationObject = initIntegrationObject(handoff.workingPath);
|
|
432
434
|
await buildIntegration(handoff, documentationObject);
|
|
433
435
|
await buildPreviews(handoff, documentationObject);
|
|
434
436
|
}
|
|
@@ -48,13 +48,13 @@ export const getPathToIntegration = (handoff: Handoff, resolveTemplatePath: bool
|
|
|
48
48
|
if (!handoff) {
|
|
49
49
|
throw Error('Handoff not initialized');
|
|
50
50
|
}
|
|
51
|
+
if (!handoff.force) {
|
|
52
|
+
const integrationPath = path.resolve(path.join(handoff.workingPath, 'integration'));
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return integrationPath;
|
|
54
|
+
if (fs.existsSync(integrationPath)) {
|
|
55
|
+
return integrationPath;
|
|
56
|
+
}
|
|
56
57
|
}
|
|
57
|
-
|
|
58
58
|
if (resolveTemplatePath) {
|
|
59
59
|
return path.resolve(path.join(handoff.modulePath, 'config', 'templates', 'integration'));
|
|
60
60
|
}
|
|
@@ -133,7 +133,9 @@ const buildIntegration = async (
|
|
|
133
133
|
rootPath ??= sourcePath;
|
|
134
134
|
|
|
135
135
|
const items = await fs.readdir(sourcePath);
|
|
136
|
+
|
|
136
137
|
const components = Object.keys(documentationObject.components);
|
|
138
|
+
const componentsWithInstances = components.filter((component) => documentationObject.components[component].instances.length > 0);
|
|
137
139
|
|
|
138
140
|
for (const item of items) {
|
|
139
141
|
const sourceItemPath = path.join(sourcePath, item);
|
|
@@ -159,7 +161,16 @@ const buildIntegration = async (
|
|
|
159
161
|
// Ensure the directory exists before writing the file
|
|
160
162
|
await fs.ensureDir(path.dirname(destItemPath));
|
|
161
163
|
// Write the rendered content to the destination path
|
|
162
|
-
await fs.writeFile(
|
|
164
|
+
await fs.writeFile(
|
|
165
|
+
destItemPath,
|
|
166
|
+
replaceHandoffImportTokens(
|
|
167
|
+
renderedContent,
|
|
168
|
+
componentsWithInstances,
|
|
169
|
+
path.parse(destItemPath).dir,
|
|
170
|
+
rootPath,
|
|
171
|
+
rootReturnPath ?? '../'
|
|
172
|
+
)
|
|
173
|
+
);
|
|
163
174
|
}
|
|
164
175
|
}
|
|
165
176
|
};
|
|
@@ -333,7 +344,13 @@ interface IntegrationTemplateContext {
|
|
|
333
344
|
documentationObject: DocumentationObject;
|
|
334
345
|
}
|
|
335
346
|
|
|
336
|
-
const replaceHandoffImportTokens = (
|
|
347
|
+
const replaceHandoffImportTokens = (
|
|
348
|
+
content: string,
|
|
349
|
+
components: string[],
|
|
350
|
+
currentPath: string,
|
|
351
|
+
rootPath: string,
|
|
352
|
+
rootReturnPath: string
|
|
353
|
+
) => {
|
|
337
354
|
getHandoffImportTokens(components, currentPath, rootPath, rootReturnPath).forEach(([token, imports]) => {
|
|
338
355
|
content = content.replaceAll(`//<#${token}#>`, imports.map((path) => `@import '${path}';`).join(`\r\n`));
|
|
339
356
|
});
|
package/src/utils/preview.ts
CHANGED
|
@@ -95,9 +95,11 @@ export const buildClientFiles = async (handoff: Handoff): Promise<string> => {
|
|
|
95
95
|
const compile = webpack(config);
|
|
96
96
|
compile.run((err, stats) => {
|
|
97
97
|
if (err) {
|
|
98
|
-
let error = 'Errors encountered trying to build preview styles.\n';
|
|
98
|
+
let error = chalk.red('Errors encountered trying to build preview styles.') + '\n The integration sass expects a token that isn\'t found in your Figma component.\n';
|
|
99
99
|
if (handoff.debug) {
|
|
100
|
-
error += err.stack || err;
|
|
100
|
+
error += chalk.yellow('\n\n---------- Sass Build Error Trace ---------- \n') + err.stack || err;
|
|
101
|
+
}else{
|
|
102
|
+
error += 'Add the --debug flag to see the full error trace\n\n';
|
|
101
103
|
}
|
|
102
104
|
return reject(error);
|
|
103
105
|
}
|
|
@@ -105,9 +107,11 @@ export const buildClientFiles = async (handoff: Handoff): Promise<string> => {
|
|
|
105
107
|
if (stats) {
|
|
106
108
|
if (stats.hasErrors()) {
|
|
107
109
|
let buildErrors = stats.compilation.errors?.map((err) => err.message);
|
|
108
|
-
let error = 'Errors encountered trying to build preview styles.\n';
|
|
110
|
+
let error = chalk.red('Errors encountered trying to build preview styles.') + '\nThe integration sass expects a token that isn\'t found in your Figma component.\n';
|
|
109
111
|
if (handoff.debug) {
|
|
110
|
-
error += buildErrors;
|
|
112
|
+
error += chalk.yellow('\n\n---------- Sass Build Error Trace ---------- \n') + buildErrors;
|
|
113
|
+
}else{
|
|
114
|
+
error += 'Add the --debug flag to see the full error trace\n\n';
|
|
111
115
|
}
|
|
112
116
|
return reject(error);
|
|
113
117
|
}
|