-
Notifications
You must be signed in to change notification settings - Fork 715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Annotation label <foreignobject> render #1383
Annotation label <foreignobject> render #1383
Conversation
Add option to pass in an element to render as a label as a child. Uses <foreignObject> to allow user to pass in an HTML element. Related to this discussion: airbnb#1173 This has the benefit of letting the element handle text reflow, with the drawback being that the user need to manage min and max width of the container element they render. This approach seems much better imo, favouring composability over configuration which is much more in line with the philosophy of d3.
Add witdth and height to <foreignObject>. Worked for Chrome but was not displaying anything for Safari.
Not sure how idomatic all the `dive()`s are, but I've heard complaints about them so I'm guess it's the way to go.
Example of the annotation in action. Notice the Screen.Recording.2021-11-26.at.3.31.39.pm.mov@williaster Let me know what you think. Made this non-breaking as possible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
hey @valtism , sorry I was away for all of Dec and am just getting back into the swing of things. will try to review/land this asap! (next day or two) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woweee @valtism this one looks great 💯 thanks for adding this, it's a huge improvement for additional flexibility! 🔥 Can't wait to use it.
I had a couple suggestions, mostly about moving out the html-based label into its own file to support easier import and documentation.
@@ -15,6 +15,8 @@ export type LabelProps = { | |||
backgroundPadding?: number | { top?: number; right?: number; bottom?: number; left?: number }; | |||
/** Additional props to be passed to background SVGRectElement. */ | |||
backgroundProps?: React.SVGProps<SVGRectElement>; | |||
/** Pass in a custom element as the label to style as you like. Renders inside a <foreignObject> */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit – period for docs.
/** Pass in a custom element as the label to style as you like. Renders inside a <foreignObject> */ | |
/** Pass in a custom element as the label to style as you like. Renders inside a <foreignObject>. */ |
I wonder also if it'd be worth noting from the original issue something like
Note that copy/pasting content from a browser may not work if you use this option because not all non-browser SVG renderers render HTML
<foreignObject>
s
I'm actually not sure if this is true since the DOM tree in the implementation has a div <foreignObject><div>...
so maybe don't have to worry about it for now. cc @richsilv
Rename ForeignObjectLabel -> HtmlLabel Split out HtmlLabel and LabelAnchorLine to separate components. Export HtmlLabel as a separate component as it uses a small subset of the shared props.
@williaster thanks for the great feedback! I've incorporated everything you mentioned, but I'm not entirely sure how to test to see if the new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for iterating 🙌 docs look good!
fyi you can check by
- rebuilding the package of interest
yarn build:workspaces --workspaces=@visx/drag --esm --watch
(the demo site pulls from theesm/
build, this is documented inCONTRIBUTING.md
but is subtle) - start the demo site dev server
yarn dev:demo
(or frompackages/visx-demo
runyarn dev
) - visit http://localhost:3000/docs/annotation (or whatever)
I had two minor comments based on playing with it a bit. I might follow up with adding an svg <> html
toggle in the demo for easier testing, so I'm happy to make those two tweaks in that PR if you'd rather merge as is.
pointerEvents="none" | ||
className={cx('visx-annotationlabel', className)} | ||
> | ||
{showAnchorLine && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/> | ||
)} | ||
<foreignObject width={width} height={height} overflow="visible"> | ||
<div ref={labelRef} style={wrapperStyle}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when I was playing with this I found myself adding a bunch of styles to a div
in children
, I wonder if we should just expose this so users don't need an extra DOM element? something like containerStyle?: React.CSSProperties
and then we can spread it in like style={containerStyle ? { ...wrapperStyle, containerStyle } : wrapperStyle
shallow( | ||
<Label title="title test" showBackground resizeObserverPolyfill={ResizeObserver} />, | ||
).find('rect'), | ||
shallow(<Label title="title test" showBackground resizeObserverPolyfill={ResizeObserver} />) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙏 thanks for fixing these
Hey @valtism I have some time today so am gonna land this and make those changes in another PR. Awesome job here! 🎉 |
🎉 This PR is included in version |
@williaster Perfect. I'm not precious about my code, so thanks for making those fixes. Look forward to using it 😊 |
🚀 Enhancements
Add option to pass in an element to render as a label as a child.
Uses to allow user to pass in an HTML element.
Related to this discussion: #1173
This has the benefit of letting the element handle text reflow, with
the drawback being that the user need to manage min and max width of
the container element they render.
This approach seems much better imo, favouring composability over
configuration which is much more in line with the philosophy of d3.