Skip to content

Commit fa9b63f

Browse files
committed
fix(ui,sdk): correct namespace migration contract
1 parent 4faed8d commit fa9b63f

8 files changed

Lines changed: 35 additions & 11 deletions

File tree

.changeset/css-variable-namespaces-ui.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
'@workflowbuilder/ui': major
33
---
44

5-
Generated Figma design tokens move from `--wb-<token>` to `--wb-ds-<token>` with no compatibility aliases. Replace the generated-token prefix in consumer overrides; `--wb-public-*` component variables are unchanged.
5+
Generated Figma design tokens move from `--ax-<token>` to `--wb-ds-<token>` with no compatibility aliases. Replace the generated-token prefix in consumer overrides; public component variables migrate separately from `--ax-public-*` to `--wb-public-*`.

.changeset/public-variable-namespace.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
'@workflowbuilder/sdk': major
44
---
55

6-
Public component CSS variables use the `--wb-public-*` prefix with no compatibility aliases. Replace the legacy public prefix in consumer overrides.
6+
Public component CSS variables move one-to-one from `--ax-public-*` to `--wb-public-*`, with no compatibility aliases. Replace that prefix in consumer overrides.

apps/docs/src/components/ui-examples/form-fields.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.example-stack {
22
display: flex;
33
flex-direction: column;
4-
gap: var(--wb-space-100);
4+
gap: var(--wb-ds-space-100);
55
}
66

77
.example-wrap {

packages/sdk/sdk-restructuring.decision-log.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
> **Status: archival.** This log describes the factory-based public API (`createWorkflowBuilder({...})`) that was the SDK entry point as of 22.04.2026. Superseded by `refactor/wb-root-context``createWorkflowBuilder`, `Editor`, `WorkflowBuilderConfig`, `WorkflowBuilderInstance(Props)`, and `defineNodeTemplate` are all gone; the entry point is now `<WorkflowBuilder.Root>`. References below describe the world as of the decision date and are intentionally not rewritten — see current SDK exports in `packages/sdk/src/index.ts` for the post-refactor surface.
88
9+
> **CSS namespace note:** `--wb-background-color` references below preserve the historical name. The supported control is now `--wb-public-background-color`.
10+
911
## Context
1012

1113
Phase 1 of the SDK work shipped `@workflowbuilder/sdk` as a thin facade over `apps/frontend`: the SDK's `src/index.ts` barrel just re-exported `Editor` and `createWorkflowBuilder` from the frontend via `@workflow-builder/frontend/app/*` tsconfig paths and Vite aliases. That worked as a distribution shell but left a mess underneath — "frontend" was simultaneously an SPA and the canonical source of the editor component, and the SDK looked like it was what it wasn't.
@@ -136,7 +138,7 @@ Two regressions and one gap became visible only once an external consumer app ac
136138

137139
- **i18n regression (Phase 3a side-effect).** Plugins used to register translations via module-load side effects, which populated the shared `pluginsResource` before `i18n.init()` read it. Phase 3a moved plugin registration into the `createWorkflowBuilder({ plugins: [...] })` factory call, which executes **after** the SDK module graph has initialized i18next — so `registerPluginTranslation` updates a module-level object that i18next no longer consults. Plugin keys (`plugins.flowRunner.groupFlow`, `plugins.help.helpSupport`, etc.) surfaced as raw strings in the UI. Fix: `registerPluginTranslation` now calls `i18n.addResourceBundle(lang, 'translation', { plugins: ... }, true, true)` in addition to updating `pluginsResource`. Works regardless of when plugins register relative to i18next init.
138140

139-
- **CSS incompleteness — SDK's `index.css` was a partial copy of demo's `global.css`.** Missing `body { margin: 0; background-color: var(--wb-public-background-color); overflow: hidden; }` rule left consumer apps with a white canvas instead of the tokenized grey background. Missing `@layer ui { @layer base, component; }` sub-layer declaration. Missing Google Fonts `@import` for Poppins left consumers with `sans-serif` fallback (since SDK's font stack was `'Poppins', sans-serif`). All three folded into [`packages/sdk/src/index.css`](./src/index.css). The Poppins `@import` plus a widened fallback chain (`system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif`) means consumers get a correct render without wiring up Google Fonts themselves.
141+
- **CSS incompleteness — SDK's `index.css` was a partial copy of demo's `global.css`.** Missing `body { margin: 0; background-color: var(--wb-background-color); overflow: hidden; }` rule left consumer apps with a white canvas instead of the tokenized grey background. Missing `@layer ui { @layer base, component; }` sub-layer declaration. Missing Google Fonts `@import` for Poppins left consumers with `sans-serif` fallback (since SDK's font stack was `'Poppins', sans-serif`). All three folded into [`packages/sdk/src/index.css`](./src/index.css). The Poppins `@import` plus a widened fallback chain (`system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif`) means consumers get a correct render without wiring up Google Fonts themselves.
140142

141143
- **CSS `@import` ordering.** CSS spec requires `@import` before every other statement except `@charset` and _empty_ `@layer` declarations. The sub-layer block (`@layer ui { @layer base, component; }`) has a body and therefore counts as a statement — it must come **after** all `@import`s. PostCSS flagged this in demo's build. Reordered.
142144

@@ -164,7 +166,7 @@ Smaller follow-ups from the next review pass. None are architectural; together t
164166

165167
- **`@xyflow/react` peer-dep range tightened.** `>=12.0.0` accepted any future major; replaced with `^12.0.0` to keep semver-major changes from auto-installing into consumer apps without us having validated the SDK against them.
166168

167-
- **CSS body reset documented.** `packages/sdk/src/index.css` resets `body` (`margin: 0`, `background-color: var(--wb-public-background-color)`, `overflow: hidden`) inside `@layer reset` — the lowest-precedence layer in the SDK's cascade, so consumer rules win without `!important`. The behaviour is still a surprise to a consumer who imports `style.css`, especially the `overflow: hidden` (which prevents page-level scrolling outside the editor). Added a `packages/sdk/README.md` documenting the resets, what they do, and how to override. The README is intentionally minimal — broader consumer docs (install / usage / screenshots) ride on the npm-publish prep that's still deferred.
169+
- **CSS body reset documented.** `packages/sdk/src/index.css` resets `body` (`margin: 0`, `background-color: var(--wb-background-color)`, `overflow: hidden`) inside `@layer reset` — the lowest-precedence layer in the SDK's cascade, so consumer rules win without `!important`. The behaviour is still a surprise to a consumer who imports `style.css`, especially the `overflow: hidden` (which prevents page-level scrolling outside the editor). Added a `packages/sdk/README.md` documenting the resets, what they do, and how to override. The README is intentionally minimal — broader consumer docs (install / usage / screenshots) ride on the npm-publish prep that's still deferred.
168170

169171
**Why:** the schema move closes the gap left after § 8 — once the public barrel is curated, anything still in it has to clear the same scope-boundary bar. The default-export cleanup is hygiene against a lint convention that wasn't enforced as a rule. The peer-dep tightening protects consumers against drive-by majors. The README closes the most likely "I imported your CSS and now my page can't scroll" support ticket.
170172

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { TransformedToken } from 'style-dictionary';
2+
import { describe, expect, it } from 'vitest';
3+
4+
import { cssVariableName } from './css-variable-name';
5+
6+
describe('cssVariableName', () => {
7+
it('moves the wb prefix into the design-system namespace', () => {
8+
const token = { path: ['wb', 'colors', 'brand'] } as TransformedToken;
9+
10+
expect(cssVariableName(token)).toBe('wb-ds-colors-brand');
11+
});
12+
13+
it('rejects names outside the wb namespace', () => {
14+
const token = { path: ['colors', 'brand'] } as TransformedToken;
15+
16+
expect(() => cssVariableName(token)).toThrow('Expected token name to start with "wb-", received "colors-brand"');
17+
});
18+
});

packages/tokens/src/css-variable-name.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@ import StyleDictionary, { TransformedToken } from 'style-dictionary';
33
const kebabName = StyleDictionary.hooks.transforms['name/kebab'].transform;
44

55
export function cssVariableName(token: TransformedToken): string {
6-
return String(kebabName(token, {}, {})).replace(/^wb-/, 'wb-ds-');
6+
const name = String(kebabName(token, {}, {}));
7+
if (!name.startsWith('wb-')) {
8+
throw new Error(`Expected token name to start with "wb-", received "${name}"`);
9+
}
10+
return name.replace(/^wb-/, 'wb-ds-');
711
}

packages/ui/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Workflow Builder SDK.
2525
IconSwitch, Checkbox, RadioButton, SegmentPicker, DatePicker, Accordion,
2626
Avatar, Snackbar, Status, Separator, plus the NodePanel / NodeIcon /
2727
NodeDescription / EdgeLabel diagram primitives.
28-
- **Theming** via `--wb-ds-*` design tokens, isolated in cascade layers
28+
- **Theming** via `--ax-*` design tokens, isolated in cascade layers
2929
(`@layer ui.base, ui.component`) so app styles win without `!important` and
3030
components retheme cleanly.
3131
- **Multi-entry build** with per-component subpath exports

packages/ui/src/components/date-picker/date-picker.module.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
.calendar {
3131
composes: wb-text-body-s from global;
32-
font-size: var(--wb-font-size-150);
32+
font-size: var(--wb-ds-font-size-150);
3333
font-weight: 400;
3434
line-height: 130%;
3535
background: var(--wb-public-date-picker-dropdown-background);
@@ -59,13 +59,13 @@
5959
}
6060

6161
.calendar :global(.rdp-weekday) {
62-
font-size: var(--wb-font-size-150);
62+
font-size: var(--wb-ds-font-size-150);
6363
font-weight: 400;
6464
line-height: 130%;
6565
}
6666

6767
.calendar :global(.rdp-month_caption) {
68-
font-size: var(--wb-font-size-150);
68+
font-size: var(--wb-ds-font-size-150);
6969
font-weight: 600;
7070
line-height: 130%;
7171
}
@@ -84,7 +84,7 @@
8484
.calendar :global(.rdp-selected .rdp-day_button) {
8585
background-color: var(--wb-public-date-picker-date-selected-background-color);
8686
color: var(--wb-public-date-picker-date-selected-color);
87-
font-size: var(--wb-font-size-150);
87+
font-size: var(--wb-ds-font-size-150);
8888
font-weight: 600;
8989
line-height: 130%;
9090
}

0 commit comments

Comments
 (0)