Add Floating Comments to Images
It's easy to add floating comments into your own images, just like Quip's standard @Image. ImageRecord natively supports a canvas that gives added transparently to support commenting.
First, create an ImageRecord
that stores the image you like.
Render a quip.apps.ui.Image
component that will display that record and that will store the node reference into a React variable - we'll need that to add comments in the right place. Here's an example of how you may want to render it:
- Typescript
- Javascript
<quip.apps.ui.Image
record={imageRecord}
responsiveToContainerWidth={true}
allowResizing={false}
onWidthAndAspectRatioUpdate={() => {}}
ref={this.imageNodeRef} />
<quip.apps.ui.Image
record={imageRecord}
responsiveToContainerWidth={true}
allowResizing={false}
onWidthAndAspectRatioUpdate={() => {}}
ref={this.imageNodeRef} />
Finally, create a method to handle clicks on the image - the easiest way to do it is to wrap the quip.apps.ui.Image
component with a div that triggers the method using the onClick event:
- Typescript
- Javascript
imageClickHandler = (e: React.MouseEvent<HTMLDivElement>) => {
if (this.imageNodeRef.current) {
this.imageNodeRef.current.addCommentAtPoint(e.clientX, e.clientY);
}
}
// ... the rest of the component goes here
render() {
return <div onClick={this.imageClickHandler}>
<quip.apps.ui.Image ... />
</div>;
}
imageClickHandler = (e) => {
if (this.imageNodeRef.current) {
this.imageNodeRef.current.addCommentAtPoint(e.clientX, e.clientY);
}
}
// ... the rest of the component goes here
render() {
return <div onClick={this.imageClickHandler}>
<quip.apps.ui.Image ... />
</div>;
}
Voilà! You can now click anywhere on the image and add a comment in the right place!
Here's the full snippet:
- Typescript
- Javascript
import React, { Component, Ref } from "react";
import quip from "quip-apps-api";
interface ImageWithCommentsProps {
record: quip.apps.ImageRecord;
}
class ImageWithComments extends Component<ImageWithCommentsProps> {
imageNodeRef: Ref<quip.apps.ui.Image> = React.createRef()
imageClickHandler = (e: React.MouseEvent<HTMLDivElement>) => {
if (this.imageNodeRef.current) {
this.imageNodeRef.current.addCommentAtPoint(e.clientX, e.clientY);
}
}
render() {
const {imageRecord} = this.props;
return (
<div onClick={this.imageClickHandler}>
<quip.apps.ui.Image
record={imageRecord}
responsiveToContainerWidth={true}
allowResizing={false}
onWidthAndAspectRatioUpdate={() => {}}
ref={this.imageNodeRef} />
</div>
);
}
}
export default ImageWithComments;
import React, { Component } from "react";
import PropTypes from "prop-types";
import quip from "quip-apps-api";
class ImageWithComments extends Component {
imageNodeRef = React.createRef()
imageClickHandler = (e) => {
if (this.imageNodeRef.current) {
this.imageNodeRef.current.addCommentAtPoint(e.clientX, e.clientY);
}
}
render() {
const {imageRecord} = imageRecord;
return (
<div onClick={this.imageClickHandler}>
<quip.apps.ui.Image
record={imageRecord}
responsiveToContainerWidth={true}
allowResizing={false}
onWidthAndAspectRatioUpdate={() => {}}
ref={node => this.imageNode = node} />
</div>
);
}
}
ImageWithComments.propTypes = {
record: PropTypes.instanceOf(quip.apps.ImageRecord),
};
export default ImageWithComments;
See ImageRecord
for a full description of the APIs.