fix #220 - feat: Add a non-React host example for the Diagram Editor - #288
Conversation
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
✅ Deploy Preview for openworkflow-editor ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| "build:dev": "pnpm clean && tsc -p tsconfig.json && vite build", | ||
| "build:prod": "pnpm lint && pnpm clean && tsc -p tsconfig.json && vite build && pnpm test && pnpm test-e2e", | ||
| "test": "vitest run --passWithNoTests", | ||
| "test": "vitest run", |
There was a problem hiding this comment.
This change is out of scope but we don't need --passWithNoTests anymore
| "build:dev": "pnpm clean && tsc -p tsconfig.json && vite build", | ||
| "build:prod": "pnpm run build:dev && pnpm test", | ||
| "test": "vitest run --passWithNoTests" | ||
| "test": "vitest run" |
There was a problem hiding this comment.
This change is out of scope but we don't need --passWithNoTests anymore
There was a problem hiding this comment.
Pull request overview
Adds a new “vanilla” (non-React host) example that embeds @openworkflowspec/diagram-editor via a Web Component, making it easier for non-React consumers to integrate the Diagram Editor while keeping React encapsulated behind a Custom Element API.
Changes:
- Adds a new
examples/vanilla-web-componentworkspace package with Vite dev server, unit tests (Vitest), and e2e tests (Playwright). - Updates the pnpm workspace to include
examples/*and updates the lockfile accordingly. - Tightens test scripts in existing packages by removing
--passWithNoTests.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Adds examples/* to the pnpm workspace so examples are first-class workspaces. |
| pnpm-lock.yaml | Records the new example importer and its dependencies. |
| packages/open-workflow-diagram-editor/package.json | Changes test script to fail when no tests are found. |
| packages/i18n/package.json | Changes test script to fail when no tests are found. |
| examples/vanilla-web-component/package.json | Defines the new example package scripts, deps, and tooling. |
| examples/vanilla-web-component/index.html | Adds the demo host page that embeds the custom element and loads sample content. |
| examples/vanilla-web-component/src/index.ts | Registers the custom element and imports required editor styles. |
| examples/vanilla-web-component/src/diagram-editor-element.ts | Implements the Custom Element wrapper that mounts/unmounts a React root and renders DiagramEditor. |
| examples/vanilla-web-component/src/sample-workflow.ts | Provides sample Serverless Workflow YAML used by the demo/e2e checks. |
| examples/vanilla-web-component/vite.config.ts | Configures Vite dev server (port 6007) and build behavior for the example. |
| examples/vanilla-web-component/vitest.config.ts | Configures Vitest (jsdom, globals, css, include patterns). |
| examples/vanilla-web-component/playwright.config.ts | Configures Playwright e2e execution against the Vite dev server. |
| examples/vanilla-web-component/tests/diagram-editor-element.test.ts | Adds unit tests validating element registration and prop wiring. |
| examples/vanilla-web-component/tests-e2e/diagram-editor.spec.ts | Adds an e2e smoke test validating the editor renders and shows nodes. |
| examples/vanilla-web-component/tsconfig.json | Adds TS config for the example package. |
| examples/vanilla-web-component/README.md | Documents usage, attributes, and styling requirements of the example. |
| examples/vanilla-web-component/.oxlintrc.json | Inherits repo lint configuration for the example package. |
| examples/vanilla-web-component/.oxfmtrc.json | Inherits repo formatting configuration for the example package. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 18 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (2)
examples/vanilla-web-component/README.md:46
- The README’s attributes table lists no default for
locale, but the web component implementation falls back to"en"when the attribute is omitted. This is a documentation mismatch that can confuse consumers of the example.
| `locale` | `string` | - | Language locale for the editor UI |
examples/vanilla-web-component/index.html:32
- CSS property indentation is inconsistent here (the
text-alignline is over-indented compared to the rest of theh1rules), which looks like an accidental formatting error and makes the example harder to read.
h1 {
margin: 16px;
font-size: 1.25rem;
font-weight: 600;
text-align: center;
}
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
cheryl7114
left a comment
There was a problem hiding this comment.
agree with Lorna's comment of the README, other than that looks good
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
…a-non-React-host-example-for-the-Diagram-Editor Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (1)
packages/open-workflow-diagram-editor/README.md:34
- The README link to the example is a repo-relative path (
../../examples/...). That works on GitHub but will be broken for consumers reading the package README on npm (the published package won’t include the repo’sexamples/folder). Prefer an absolute GitHub URL (or a full URL to the docs site) so the reference works everywhere.
If your application doesn't use React, you can embed the editor as a Web Component.
See the [vanilla Web Component example](../../examples/vanilla-web-component/) for a working setup.
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 21 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (3)
packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts:41
- Inside the effect,
normalizeColorMode(colorMode)is called multiple times, which makes it easy for the branches to get out of sync if the normalization logic changes. Store the normalized value once per effect execution and reuse it.
useEffect(() => {
if (normalizeColorMode(colorMode) !== "system") {
setResolvedColorMode(normalizeColorMode(colorMode));
return;
packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts:36
normalizeColorMode(colorMode)is computed twice in theuseStateinitializer, which is harder to read and duplicates work. Compute the normalized value once and reuse it for the initial resolved mode.
This issue also appears on line 38 of the same file.
export function useResolvedColorMode(colorMode: ColorMode): ResolvedColorMode {
const [resolvedColorMode, setResolvedColorMode] = useState<ResolvedColorMode>(
normalizeColorMode(colorMode) === "system" ? getSystemColorMode() : normalizeColorMode(colorMode),
);
packages/open-workflow-diagram-editor/tests/hooks/useResolvedColorMode.test.ts:88
- This test name says it “falls back to "system"”, but
useResolvedColorModenever returns "system" (it returns the resolved "light"/"dark"). Consider renaming the test and asserting that the hook actually takes the "system" path (e.g. it registers a media-query listener).
it('falls back to "system" for an unknown colorMode value', () => {
matchesDark = false;
// @ts-expect-error testing runtime behavior with an invalid colorMode value
const { result } = renderHook(() => useResolvedColorMode("invalid"));
expect(result.current).toBe("light");
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 21 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (3)
examples/vanilla-web-component/README.md:48
- The README’s attributes table lists no defaults for
content,locale, andread-only, butDiagramEditorElementinitializescontentto an empty string, defaultslocaleto"en", and treatsread-onlyasfalsewhen the attribute is absent. Updating the table avoids misleading consumers of the example.
| -------------------- | ------------------------------- | ---------- | -------------------------------------------------------- |
| `content` (property) | `string` | - | Serverless Workflow specification in YAML or JSON format |
| `locale` | `string` | - | Language locale for the editor UI |
| `color-mode` | `'light' \| 'dark' \| 'system'` | `"system"` | Color theme for the editor |
| `read-only` | boolean | - | Enable read-only mode to prevent editing |
packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts:24
normalizeColorModeis typed as acceptingColorMode, but its implementation (and the accompanying test) is explicitly validating runtime-invalid values. Typing the parameter asunknown(or at leaststring) makes the intent clear and prevents type-aware linters from flagging the fallback branch as unreachable.
function normalizeColorMode(colorMode: ColorMode): ColorMode {
return colorMode === "light" || colorMode === "dark" || colorMode === "system" ? colorMode : "system";
}
packages/open-workflow-diagram-editor/tests/hooks/useResolvedColorMode.test.ts:83
- This test title says the hook “falls back to "system"” but asserts the resolved mode ("light") rather than the normalized input. Renaming the test to describe the actual behavior under test makes failures easier to interpret.
it('falls back to "system" for an unknown colorMode value', () => {
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 21 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (1)
examples/vanilla-web-component/src/diagram-editor-element.ts:68
(this.getAttribute("color-mode") as ColorMode) ?? "system"casts away thenullcase before the nullish-coalescing, which makes the fallback look redundant to TypeScript readers/tools and obscures the actual runtime behavior. Coalesce first, then cast (or validate) so the intent is explicit.
colorMode: (this.getAttribute("color-mode") as ColorMode) ?? "system",
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 22 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (2)
.changeset/add-vanilla-web-component-example.md:3
- This changeset targets
@openworkflowspec/vanilla-web-component-example, but that package is markedprivate: trueand won’t be published. Since this PR also changes the published@openworkflowspec/diagram-editorpackage (runtime behavior + README), consider retargeting the changeset to@openworkflowspec/diagram-editorso release notes land on a publishable package.
---
"@openworkflowspec/vanilla-web-component-example": minor
---
packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts:44
- The
"system"branch unconditionally callswindow.matchMedia(...)for the listener setup. IfmatchMediais not available (some non-browser runtimes / older browsers), this will throw at runtime. SincegetSystemColorMode()already tolerates missingmatchMedia, the effect should also guard and skip listener registration when unavailable.
useEffect(() => {
if (normalized !== "system") {
setResolvedColorMode(normalized);
return;
}
Signed-off-by: fantonangeli <fabrizio.antonangeli@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 23 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (2)
.changeset/add-vanilla-web-component-example.md:3
- The repo uses a fixed-version group for all
@openworkflowspec/*packages (see.changeset/config.json), so marking this example as a minor change will trigger a minor bump for the entire release set. If the example addition shouldn’t force a minor version bump for the published libraries, consider downgrading this changeset topatch(or removing it and relying on the library changeset).
---
"@openworkflowspec/vanilla-web-component-example": minor
---
packages/open-workflow-diagram-editor/src/hooks/useResolvedColorMode.ts:45
- When
normalizedfalls back to "system", the effect will later callwindow.matchMedia(...)unconditionally (line 48). In environments wherewindowexists butmatchMediais not implemented (common in jsdom unless polyfilled), this will throw. Add an early guard/return in the "system" branch before reaching thematchMediacall.
useEffect(() => {
if (normalized !== "system") {
setResolvedColorMode(normalized);
return;
}
Closes #220
Description
Add an example showing how to use
@openworkflowspec/diagram-editorfrom a non-React framework host application embedding the DE as a Web ComponentHow to test:
From the repository root:
Browse http://localhost:6007
Preview: