Skip to content

Conversation

Anemy
Copy link
Member

@Anemy Anemy commented Sep 22, 2025

External Links

Description

In the tech design for editing data models in Compass we originally opted to move a number of the customizable parts of rendering fields and field types to the consumer of the diagramming package. However we have found that doing this introduces more complexity when react flow needs to render the field or node, passing a react function can be non-serializable state and can cause unintended re-renders. Those unintended re-renders hinder performance and can cause flashes.

This pr adds new callback functions to the diagramming library, which, when supplied, render related actions for fields and nodes. We're removing the custom node actions render function prop and field name render we've added as they're now to be covered internally. Down the line if we need to add custom rendering passed by a consumer we should instead have it be something that's supplied as a generic function which we can then use with react context in the location that react flow renders as to avoid passing around components in field or node data. We should not add react functions to the node or field types that are used by React Flow.

By adding this editing capabilities to this package, we're thinking it may be of more use down the line if other folks want to have similar functionality.

Notes for Reviewers

There is still one passing of a react function in the code base, that's in the type field. That will be addressed in a later pr. We will also be adding field name renaming.

Field selection (in the story and video below) will causes flashes on slower machines. This is a result of us re-creating all of the nodes, and fields in them, on selection and reflecting their selected state there. To fix this we'll want to have the selected fields supplied with a context that the field components and listen to and update accordingly. I'll create a separate ticket for that. Branch with that work: https://github.com/mongodb-js/diagramming/compare/refactor/COMPASS-9879-update-how-field-selection-is-passed?expand=1 Tested with the stress test and it was working smoooth.

If folks from the migrator side would prefer that these editing components like the plus button to add a field don't make it into this package, we could add generic react props onto the Diagram interface, like renderFieldType. We would then render them from a react context in the Field. That would have the same intended outcome as this implementation as we would be getting rid of having those functions on the items sent to react flow.

📸 Screenshots/Screencasts

node.and.field.interactions.mp4

@Anemy Anemy requested a review from lchans September 22, 2025 18:46
@Anemy Anemy marked this pull request as ready for review September 22, 2025 18:50
@Anemy Anemy requested a review from paula-stacho September 22, 2025 18:50
line-height: 20px;
`;

const AddNestedFieldIconButton = styled.button`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to style a button rather than using the IconButton that LG provides?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LeafyGreen one was too large in terms of both size and focus state. I was thinking passing a lot of custom overriding styles would end up in a more broken state down the line if internals in LeafyGreen change and we upgrade.
https://www.mongodb.design/component/icon-button/live-example

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much would we have to override other than the style? I understand the risk with depending on LG, but this way it's completely detached from the other plus btn which should look pretty much the same. Maybe we could ask LG to support the size we need and have a follow up to include it here, or if we say diagram buttons are a special case, then let's define an IconButton here in the lib and use it for both

Copy link
Member Author

@Anemy Anemy Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only styles we're overriding. https://github.com/mongodb/leafygreen-ui/blob/main/packages/icon-button/src/IconButton/IconButton.styles.tsx

Defined a custom one that we're now using in both places. Removed icon-button from LG as we aren't using it anymore.

I'll bring it up in their slack channel. The diagram is pretty custom styles that they aren't covering though so I'm not sure it's something they'd want to add. IIRC we do have some custom IconButton styles in Compass though and some are smaller so that could be another case.

);

return (
<ObjectTypeContainer>
Copy link
Collaborator

@lchans lchans Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The {} and the icon are not quite aligned (See screenshot, the icon is a tad taller)
The plus icon is also not right aligned with the other types (there's a gap), is that intended?
Screenshot 2025-09-23 at 10 52 11 AM

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if you could add the Figma link as well in this PR? Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of IconButton also renders it weirdly when active / tabbing
Screenshot 2025-09-23 at 1 24 08 PM

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a 🎨 Figma link. I went with a custom button on the object field type add button to make that focus active state look better. We could share the same button here so they both have the same focus styles. How does that sound?
Answering your other question here as well, I went with a custom button and not icon button for the object field type as the leafygreen one was too large and I was thinking passing a lot of custom overriding styles would end up in a more broken state down the line if internals in LeafyGreen change and we upgrade.

@lchans lchans requested a review from adrianhhong September 23, 2025 03:34
if (type === 'object' && !!onClickAddFieldToObject) {
return (
<ObjectTypeContainer>
{'{}'}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't depend on the callback existence

Copy link
Collaborator

@paula-stacho paula-stacho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left one comment, otherwise looks great!

@Anemy
Copy link
Member Author

Anemy commented Sep 25, 2025

Merging this in cc @lchans @adrianhhong
Feel free to revert, or ping me anything you'd like to change and I'll open a follow up.
We have some work depending on this in #136 and #137 so I'd like to unblock them.

@Anemy Anemy merged commit 1d5885c into main Sep 25, 2025
5 checks passed
@Anemy Anemy deleted the refactor/COMPASS-9877-add-editable-node-handlers-and-interactions branch September 25, 2025 16:43
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.

3 participants