Skip to content
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

[Table] Pass parent width/height props to TruncatedFormat #1550

Merged
merged 10 commits into from
Sep 13, 2017

Conversation

gscshoyru
Copy link
Contributor

@gscshoyru gscshoyru commented Sep 11, 2017

Changes proposed in this pull request:

Pass cell height and width to child, for use in shouldComponentUpdate

The props aren't used by the element, but its presence means faster redraw for cells with truncated formats. The props are used by the element to avoid re-measuring if the parent size didn't change across updates.

Reviewers should focus on:

This is on top of another in-progress PR -- ignore the first two commits.

I'm cloning all the cell children -- does this make sense?

const modifiedChildren = React.Children.map(this.props.children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child as React.ReactElement<any>,
{parentCellHeight: style.height, parentCellWidth: style.width});
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: add spaces: { parentCellHeight: style.height, parentCellWidth: style.width }

@@ -102,7 +102,15 @@ export class Cell extends React.Component<ICellProps, {}> {
},
);

const content = <div className={textClasses}>{this.props.children}</div>;
const modifiedChildren = React.Children.map(this.props.children, (child) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

add comment somewhere explaining that parentCell{Height,Width} won't be used in the Cell except in shouldComponentUpdate

|| actualContentWidth > containerWidth
|| actualContentHeight > containerHeight;

if (isTruncated !== shouldTruncate) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Still need this?

Copy link
Contributor

Choose a reason for hiding this comment

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

@gscshoyru I think we can do away with this check now that this is a pure component.

@blueprint-bot
Copy link

Check for null to fix tests

Preview: documentation | table
Coverage: core | datetime

@tgreenwatts
Copy link
Contributor

Do we know yet if this helps perf? Or just an exercise still?

@@ -132,6 +136,11 @@ export class TruncatedFormat extends React.Component<ITruncatedFormatProps, ITru
this.setTruncationState();
}

public shouldComponentUpdate(nextProps: ITruncatedFormatProps, nextState: ITruncatedFormatState) {
return !Utils.shallowCompareKeys(this.props, nextProps)
|| !Utils.shallowCompareKeys(this.state, nextState);
Copy link
Contributor

Choose a reason for hiding this comment

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

why not an @PureRender annotation on the class like we usually do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That... probably should work? @cmslewis ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep do that!

@@ -33,6 +34,9 @@ export interface ITruncatedFormatProps extends IProps {
*/
detectTruncation?: boolean;

parentCellHeight?: string;
parentCellWidth?: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

docs? are these props even necessary here? you cast to React.ReactElement<any> above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See comments on PR -- this is explicitly necessary for the shouldComponentUpdate -- we don't actually use them, but we need them to keep from rerendering and remeasuring every time, without knowing if the size has changed.

const content = <div className={textClasses}>{this.props.children}</div>;
const modifiedChildren = React.Children.map(this.props.children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child as React.ReactElement<any>,
Copy link
Contributor

Choose a reason for hiding this comment

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

use JSX.Element in place of React.ReactElement<any> if you don't need props type

@@ -102,7 +102,15 @@ export class Cell extends React.Component<ICellProps, {}> {
},
);

const content = <div className={textClasses}>{this.props.children}</div>;
const modifiedChildren = React.Children.map(this.props.children, (child) => {
if (React.isValidElement(child)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

hmm i didn't know this method existed. is it necessary? does it actually avoid errors? my suspicion is no, and you don't need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a typeguard. Without it, child could be react element, or could be text. Hence the return, otherwise.

@cmslewis cmslewis changed the title Gsc/pass height width to formats [Table] Pass parent width/height props to TruncatedFormat Sep 13, 2017
@blueprint-bot
Copy link

Change content-width delta 1 26px

Preview: documentation | table
Coverage: core | datetime


// this is where we get our savings from the injected parent-size props.
// if they haven't changed between updates, then no need to remeasure!
if (!detectTruncation
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This doesn't quite work -- the parent heights and widths may not have changed, but the content could have. You still need to remeasure if anything changed. We can't really get savings this way.

@@ -14,7 +14,7 @@ import * as Classes from "../../common/classes";

// amount in pixels that the content div width changes when truncated vs when
// not truncated. Note: could be modified by styles
const CONTENT_DIV_WIDTH_DELTA = 25;
const CONTENT_DIV_WIDTH_DELTA = 26;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is also wrong, it comes from the right property on the div. There's a comment in sass, I'll put one here too.

@blueprint-bot
Copy link

Undo some of Chris's stuff (sorry Chris!), address comments

Preview: documentation | table
Coverage: core | datetime

@@ -152,21 +165,38 @@ export class TruncatedFormat extends React.Component<ITruncatedFormatProps, ITru
}

private setTruncationState() {
if (!this.props.detectTruncation || this.props.showPopover !== TruncatedPopoverMode.WHEN_TRUNCATED) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Whoops, @gscshoyru we'll still want these checks

|| actualContentWidth > containerWidth
|| actualContentHeight > containerHeight;

if (isTruncated !== shouldTruncate) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@gscshoyru I think we can do away with this check now that this is a pure component.

@blueprint-bot
Copy link

Remove no longer necessary if statement

Preview: documentation | table
Coverage: core | datetime

const modifiedChildren = React.Children.map(this.props.children, (child) => {
if (style != null && React.isValidElement(child)) {
return React.cloneElement(child as React.ReactElement<any>,
{parentCellHeight: style.height, parentCellWidth: style.width});
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: proper format would look something like this. but that's why we have prettier incoming.

return React.cloneElement(child as React.ReactElement<any>, {
    parentCellHeight: style.height,
    parentCellWidth: style.width,
});

@blueprint-bot
Copy link

Add back check

Preview: documentation | table
Coverage: core | datetime

@cmslewis cmslewis merged commit 6750fcd into master Sep 13, 2017
@cmslewis cmslewis deleted the gsc/pass-height-width-to-formats branch September 13, 2017 22:14
@llorca llorca mentioned this pull request Sep 15, 2017
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.

5 participants