Fix DrawIO CLI docs, refactor context menu, correct XML generation#2593
Fix DrawIO CLI docs, refactor context menu, correct XML generation#2593
Conversation
|
Co-authored-by: davydkov <[email protected]>
Co-authored-by: davydkov <[email protected]>
|
@sraphaz Can you review this? |
There was a problem hiding this comment.
@copilot fix lint issue by using flattenMarkdownOrString from @likec4/core/types, and isEmptyish from remeda
Something like
| const description = node.description && flattenMarkdownOrString(node.description) | |
| const desc = isEmptyish(description) ? '' : escapeXml(description)``` |
There was a problem hiding this comment.
Fixed in 9428ec0 - now using flattenMarkdownOrString from @likec4/core/types and isEmptyish from remeda for cleaner description/technology handling.
… handling Co-authored-by: davydkov <[email protected]>
sraphaz
left a comment
There was a problem hiding this comment.
Code review: PR #2593 — Fix DrawIO CLI docs, refactor context menu, correct XML generation
Review by @sraphaz (as requested by @davydkov).
Summary
This PR applies three sets of changes: CLI documentation fix, DrawIO context menu refactor, and XML generation adjustments. The direction is correct; there is one issue that will break the playground typecheck and a few minor suggestions.
What looks good
1. CLI docs (cli.mdx)
--output, -o→--outdir, -ois correct and matches the handler inpackages/likec4/src/cli/export/drawio/handler.ts.
2. Context menu refactor
- Extracting logic into
useDrawioActionsand the presentationalDrawioContextMenuViewreduces duplication and keeps the components easier to maintain. - Using
triggerImportin theDRAWIO_IMPORT_EVENT/DRAWIO_EXPORT_EVENTlisteners in the Provider is consistent. DrawioContextMenuViewwith explicit props (opened, onClose, menuPosition, onImport, onExport, canExport) keeps the UI testable and reusable.
3. XML (generate-drawio.ts)
- Placing
mxUserObjectafter<mxGeometry />inside each vertexmxCellis correct and aligns with what draw.io expects. - Using
flattenMarkdownOrStringandisEmptyishfor description/technology improves typing and roundtrip behavior.
Issue that breaks typecheck
openMenu in the context menu is typed only with React.MouseEvent.
In DrawioContextMenuProvider.tsx (and in the DrawioContextMenuApi type):
openMenu: (event: React.MouseEvent) => voidBut LikeC4Diagram expects (in packages/diagram/src/LikeC4Diagram.props.ts):
export type OnCanvasContextMenu = (event: ReactMouseEvent | MouseEvent) => voidSo the callback may receive either React.MouseEvent or DOM MouseEvent. The code that calls onCanvasContextMenu (e.g. ReactFlow) can pass the native event.
Effect: when passing openMenu to onCanvasContextMenu in $viewId.tsx, the playground typecheck fails with:
error TS2322: Type '(event: MouseEvent<Element, MouseEvent>) => void' is not assignable to type 'OnCanvasContextMenu'.
Types of parameters 'event' and 'event' are incompatible.
Type 'MouseEvent | React.MouseEvent<...>' is not assignable to type 'MouseEvent<Element, MouseEvent>'.
Suggested fix: accept the union in the type and in the handler:
- In
DrawioContextMenuProvider.tsx: inDrawioContextMenuApi, use
openMenu: (event: React.MouseEvent | MouseEvent) => void - In the hook that implements
openMenu(inuseDrawioActionsor whereveropenMenuis defined): use the signature
(event: React.MouseEvent | MouseEvent) => void
and keep usingevent.preventDefault(),event.clientX,event.clientY(they exist on both types). - In
DrawioContextMenu.tsx, in the render propchildren, type the argument the same way:
(onCanvasContextMenu: (event: React.MouseEvent | MouseEvent) => void) => React.ReactNode
That makes the handler compatible with OnCanvasContextMenu and the playground typecheck will pass.
Minor suggestions
-
Changeset
The bot already noted there is no changeset. Since this PR touches docs, playground, and generators, adding a changeset (e.g. patch for@likec4/docs-astro,@likec4/playground,@likec4/generators) makes sense if you intend to version these changes. -
handleImportFiletyping
InuseDrawioActions.ts,handleImportFileis typed as(e: React.ChangeEvent). For clarity and alignment with<input type="file">, consider:
(e: React.ChangeEvent<HTMLInputElement>). -
Naming
Current names (useDrawioActions,DrawioContextMenuView) are clear. An alternative used elsewhere isuseDrawioContextMenuActions+DrawioContextMenuDropdown; either is fine as long as the rest of the drawio code is consistent.
Post-fix checklist
- Update
openMenutype to(event: React.MouseEvent | MouseEvent) => void(API + hook + render prop). - Run
pnpm turbo run typecheck --filter='@likec4/playground'and ensure it passes. - (Optional) Add a changeset; (optional) type
handleImportFileasReact.ChangeEvent<HTMLInputElement>.
After that, this PR looks ready to merge from my side (assuming tests and the rest of typecheck are already green).
Description
Three DrawIO-related fixes:
1. CLI Documentation
File:
apps/docs/src/content/docs/tooling/cli.mdxChanged
--output, -o→--outdir, -oto match handler implementation.2. Context Menu Refactoring
Files:
apps/playground/src/components/drawio/*Extracted duplicated import/export logic from
DrawioContextMenuandDrawioContextMenuProvider:useDrawioActionshook: encapsulates fileInputRef, file import (FileReader → parseDrawioToLikeC4 → workspace.addFile), and export (generateDrawio → Blob download)DrawioContextMenuViewcomponent: presentational Mantine Menu rendering (props: opened, onClose, menuPosition, onImport, onExport, canExport)Both components now reuse these abstractions instead of duplicating ~80 lines of logic.
3. XML Generation Structure
File:
packages/generators/src/drawio/generate-drawio.tsFixed
mxUserObjectplacement in generated XML:Improved description/technology handling by using
flattenMarkdownOrStringfrom@likec4/core/typesandisEmptyishfrom remeda for cleaner type handling and better support for both plain strings andMarkdownOrStringobjects.This aligns with the parser's expectations and ensures roundtrip compatibility (generate → parse → generate preserves description/technology metadata).
Checklist
mainbefore creating this PR.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.