Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,60 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## \[1.2.2] - TBD

This patch release improves watch-mode reliability for patterns, broadens slot
default typing, clears downstream lint/build compatibility issues, and fixes a
few release-branch UI and dependency issues.

### Added

* Added `watchPatternDirectories` so newly created pattern subdirectories are
detected during `start` without restarting the dev server.
* Added a shared `NotFound` component and reused it for stale pattern URLs and
missing markdown pages.

### Changed

* Broadened `SlotMetadata.default` so slot defaults can be strings, numbers,
booleans, objects, arrays, or `null`.
* Refactored component and pattern directory watching through a shared
`watchEntityDirectories` helper.
* Downgraded incomplete or mid-edit pattern declarations from hard parse errors
to warnings, allowing watch mode to retry automatically after the file is
saved with valid content.
* Removed unneeded theme declarations.

### Fixed

* Fixed watch-mode rebuilds for newly added patterns by rebuilding referenced
component previews before composing the new pattern.
* Fixed pattern watcher edge cases where declaration IDs differ from directory
names, and where an initially incomplete pattern config later becomes valid.
* Fixed `.handoff.ts` declaration files not being detected by the new-entity
config-file gate.
* Extended component build-cache inputs to include pattern config files that
reference the component, preventing stale preview output after pattern changes.
* Fixed select/list handling when a component group or category value is empty.
* Fixed CSS typing issues and app build issues found during the release branch.
* Resolved `no-else-return`, `no-unused-vars`, `camelcase`, `prefer-const`,
`eqeqeq`, `no-nested-ternary`, `no-lonely-if`, and `no-use-before-define`
across static pages (catch-all docs, assets, foundations, home, system, and
design-token foundation pages).
* Removed or refactored unused `getStaticProps` context parameters, props, and
locals; normalized naming (e.g. font machine keys); simplified icon detail
routing query handling.
* Reordered helper components ahead of page components where required for
declaration order.
* Converted `getComponentPreviews` to a hoisted `function` declaration and
refactored the component token table for clearer control flow.
* Avoided iterating `Map`, `Set`, `Iterable`, and `matchAll` results directly in
`for...of` where the compile target requires `--downlevelIteration`.

### Security

* Updated Vite to address a security issue.

## \[1.2.1] - 2026-04-08

This is a minor release that fixes a bug in the new config diff calculator.
Expand Down
94 changes: 47 additions & 47 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "handoff-app",
"version": "1.2.1",
"version": "1.2.2-7",
"description": "Automated documentation toolchain for building client side documentation from figma",
"author ": {
"name": "Convertiv",
Expand Down
22 changes: 19 additions & 3 deletions src/app-builder/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ import path from 'path';
import Handoff from '..';
import { buildComponents } from '../pipeline/components';
import { buildPatterns } from '../pipeline/patterns';
import processComponents from '../transformers/preview/component/builder';
import { buildMainCss } from '../transformers/preview/component/css';
import { buildMainJS } from '../transformers/preview/component/javascript';
import processComponents from '../transformers/preview/component/builder';
import { Logger } from '../utils/logger';
import { generateTokensApi, persistClientConfig } from './client-config';
import { getAppPath, syncPublicFiles } from './paths';
import { WatcherState, getRuntimeComponentsPathsToWatch, watchAppSource, watchComponentDirectories, watchGlobalEntries, watchPages, watchPublicDirectory, watchRuntimeComponents, watchRuntimeConfiguration } from './watchers';
import {
WatcherState,
getRuntimeComponentsPathsToWatch,
watchAppSource,
watchComponentDirectories,
watchGlobalEntries,
watchPages,
watchPatternDirectories,
watchPublicDirectory,
watchRuntimeComponents,
watchRuntimeConfiguration,
} from './watchers';
import { createWebSocketServer } from './websocket';

const escapeForSingleQuotedJsString = (value: string): string => value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
Expand Down Expand Up @@ -46,10 +57,13 @@ const initializeProjectApp = async (handoff: Handoff): Promise<string> => {

// Copy custom theme CSS if it exists in the user's project
const customThemePath = path.resolve(handoff.workingPath, 'theme.css');
const destPath = path.resolve(appPath, 'css', 'theme.css');
if (fs.existsSync(customThemePath)) {
const destPath = path.resolve(appPath, 'css', 'theme.css');
await fs.copy(customThemePath, destPath, { overwrite: true });
Logger.success(`Custom theme.css loaded`);
} else {
// create a empty theme.css file
await fs.writeFile(destPath, '');
}

// Prepare project app configuration using stable placeholder replacement.
Expand Down Expand Up @@ -211,12 +225,14 @@ export const watchApp = async (handoff: Handoff): Promise<void> => {
runtimeComponentsWatcher: null,
runtimeConfigurationWatcher: null,
componentDirectoriesWatcher: null,
patternDirectoriesWatcher: null,
};

watchPublicDirectory(handoff, wss, state, chokidarConfig);
watchRuntimeComponents(handoff, state, getRuntimeComponentsPathsToWatch(handoff));
watchRuntimeConfiguration(handoff, state);
watchComponentDirectories(handoff, state, chokidarConfig);
watchPatternDirectories(handoff, state, chokidarConfig);
watchGlobalEntries(handoff, state, chokidarConfig);
watchPages(handoff, chokidarConfig);
};
Expand Down
Loading