Skip to content

refactor(joint-react): unified ElementRecord / LinkRecord with portMap, labelMap, style#3253

Open
kumilingus wants to merge 11 commits intoclientIO:devfrom
kumilingus:refactors/naming
Open

refactor(joint-react): unified ElementRecord / LinkRecord with portMap, labelMap, style#3253
kumilingus wants to merge 11 commits intoclientIO:devfrom
kumilingus:refactors/naming

Conversation

@kumilingus
Copy link
Copy Markdown
Contributor

@kumilingus kumilingus commented Mar 29, 2026

Summary

Replaces the multi-type system (PortalElementRecord, NativeElementRecord, AnyElementRecord, etc.) with a single ElementRecord and LinkRecord that support both declarative and native JointJS formats.

New API

ElementsElementRecord<D> extends dia.Element.Attributes:

  • portMap?: Record<string, ElementPort> — declarative ports (converted to native ports by mapper)
  • portStyle?: Partial<ElementPort> — default style for all ports in portMap
  • ports — native JointJS format, passed through as-is
  • data?: D — custom user data

LinksLinkRecord<D> extends dia.Link.Attributes:

  • style?: LinkStyle — declarative link presentation (color, width, markers, etc.)
  • labelMap?: Record<string, LinkLabel> — declarative labels (converted to native labels array by mapper)
  • labelStyle?: Partial<LinkLabel> — default style for all labels in labelMap
  • labels — native JointJS Label[] format, passed through as-is
  • data?: D — custom user data

What changed

  • Single type per cell: ElementRecord and LinkRecord replace 6 types (Portal*, Native*, Any*)
  • portMap / labelMap: declarative (Record-keyed) ports and labels use new field names, avoiding collision with native ports/labels
  • style: link presentation fields (color, width, sourceMarker, etc.) moved from top-level into style: { ... } object
  • Extends JointJS attributes: both types extend dia.*.Attributes — all native properties pass through
  • Simplified generics: data?: D is always optional (no conditional types), interfaces are extensible via extends
  • data required in hooks: ElementWithLayout and ResolvedLink guarantee data: D (always present at runtime)
  • Sub-type renames: ElementRecordPortElementPort, LinkRecordStyleLinkStyle, LinkRecordLabelLinkLabel
  • Mapper detection: forward mapper checks for portMap/labelMap presence (no type field discriminant needed). Throws if both declarative and native formats are provided.
  • isShallowEqual: widened to object | undefined (generic utility)
  • Test file renames: use-flat-element-data.test.tsuse-element-defaults.test.ts, use-flat-link-data.test.tsuse-link-defaults.test.ts

Removed from public API

  • PortalElementRecord, NativeElementRecord, AnyElementRecord
  • PortalLinkRecord, NativeLinkRecord, AnyLinkRecord
  • MixedElementRecord, MixedLinkRecord
  • FlatElementPort, FlatLinkLabel, FlatLinkPresentationData

Test plan

  • npx tsc --noEmit — 0 new errors
  • yarn jest — 533 pass, pre-existing failures only
  • Storybook renders correctly
  • Portal elements with portMap render ports
  • Native elements with ports pass through
  • Links with style render correctly
  • Links with labelMap render labels
  • Native links with labels array pass through

🤖 Generated with Claude Code

kumilingus and others added 11 commits March 29, 2026 12:36
…rd types

- Split ElementRecord/LinkRecord into portal vs native discriminated unions
- Rename FlatElementPort → ElementRecordPort, FlatLinkLabel → LinkRecordLabel, FlatLinkPresentationData → LinkRecordPresentation
- Rename MixedElementRecord → AnyElementRecord, MixedLinkRecord → AnyLinkRecord
- Convert NativeElementRecord/NativeLinkRecord to interfaces (extends dia.*.Attributes)
- Simplify generics: remove conditional types, use simple interfaces with data?: D
- Make data required in ElementWithLayout and ResolvedLink (always present at runtime)
- Fix joint.d.ts: Link.Attributes extends GenericAttributes (not Cell.GenericAttributes)
- Update all stories/demos to use specific types (ElementRecord, LinkRecord, NativeElementRecord)
- Rename test files to match hook names (use-element-defaults, use-link-defaults)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kumilingus kumilingus requested a review from samuelgja March 29, 2026 22:04
@kumilingus kumilingus changed the title refactor(joint-react): type system — portal vs native record split refactor(joint-react): unified ElementRecord / LinkRecord with portMap, labelMap, style Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant