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

Add ITreeNode.nodeData property #2132

Merged
merged 11 commits into from
Mar 7, 2018
Merged

Conversation

izikorgad
Copy link
Contributor

@izikorgad izikorgad commented Feb 14, 2018

Fixes #1989

This feature add a new generics type prop for ITreeNode called 'nodeData'.
The user can use this property to store custom user data, object reference, etc.

Checklist

Changes proposed in this pull request:

Reviewers should focus on:

Screenshot

@palantirtech
Copy link
Member

Thanks for your interest in palantir/blueprint, @izikorgad! Before we can accept your pull request, you need to sign our contributor license agreement - just visit https://cla.palantir.com/ and follow the instructions. Once you sign, I'll automatically update this pull request.

@izikorgad
Copy link
Contributor Author

This PR is an implementation of the concept described as part of #1998 (by @yaronlavi).

@izikorgad izikorgad closed this Feb 14, 2018
@izikorgad izikorgad reopened this Feb 14, 2018
@palantirtech
Copy link
Member

Thanks for your interest in palantir/blueprint, @izikorgad! Before we can accept your pull request, you need to sign our contributor license agreement - just visit https://cla.palantir.com/ and follow the instructions. Once you sign, I'll automatically update this pull request.

@giladgray
Copy link
Contributor

@izikorgad please fill out the description up top. that's the place to note the issue number (which i already did for you)

@@ -13,7 +13,7 @@ import { safeInvoke } from "../../common/utils";
import { Collapse } from "../collapse/collapse";
import { Icon, IconName } from "../icon/icon";

export interface ITreeNode extends IProps {
export interface ITreeNode<T = {}> extends IProps {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we say T = undefined? more accurate for the default case. if you want to use <T> then you have to define 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.

When changing the generic constrain to <T = undefined>, each call to safeInvoke() won't complied:
Argument of type 'this' is not assignable to parameter of type 'TreeNode'.

I don't see the problem with the <T = {}> constrain, the user can still use the tree without declaring on any type.

Choose a reason for hiding this comment

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

This was my original intent too, but per @adidahiya requested 16 days ago:
"you can set a default for the generic type parameter so that users who don't need it won't have to specify T.
use nodeData: T where the interface is defined as ITreeNode<T = {}>, similar to queryList:
blueprint/packages/select/src/components/query-list/queryList.tsx (Line 15 in ff76c4a)"

since both of you are reviewers and contributors, I suggest you guys touch bases and sync your request.

Copy link
Contributor

Choose a reason for hiding this comment

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

i guess {} is fine, since React does the same thing and state doesn't actually default to anything (you gotta initialize it yourself)

Copy link
Contributor

@giladgray giladgray left a comment

Choose a reason for hiding this comment

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

pushed a commit to fix docs language. looks great 👍

this will ship in the next 2.0 release!

@adidahiya
Copy link
Contributor

What does usage of this new feature look like in practice? It would be helpful if you added it to the docs example. I'm pretty sure you still want an ofType utility as mentioned in #1998 (comment)

@giladgray
Copy link
Contributor

hmm yeah might want Tree.ofType<T>()

@izikorgad
Copy link
Contributor Author

Sorry, but I’m not following...
Is the ‘ofType()’ is a standard typescript method?
What exactly is the purpose of this function?

Should it be placed inside the Tree class or TreeNode class?

Something like that:

public static ofType<T>() {
    return TreeNode as new () => TreeNode<T>;
}

@giladgray
Copy link
Contributor

giladgray commented Feb 16, 2018

@izikorgad check out the source code for our select components (and usages thereof, like the examples), that's where we "pioneered" this approach: https://github.com/palantir/blueprint/blob/develop/packages/select/src/components/select/select.tsx#L90-L92

@giladgray
Copy link
Contributor

the method is essential for typescript consumers to apply <T> to the generic component.
generic components defy JSX, as they would overload the <> tag symbols, so you have to declare a local variable with the generic parameter applied:

<Select<IFilm> props> // error

const FilmSelect = Select.ofType<IFilm>();
<FilmSelect props> // ok

@izikorgad
Copy link
Contributor Author

OK.
I've added ofType to both Tree and TreeNode components.
Please review.

@adidahiya adidahiya self-assigned this Feb 19, 2018
@@ -59,6 +63,10 @@ export class Tree extends React.Component<ITreeProps, {}> {

private nodeRefs: { [nodeId: string]: HTMLElement } = {};

constructor(props?: ITreeProps<T>, context?: any) {
super(props, context);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

whoa whoa remove this constructor, not necessary!

return TreeNode as new () => TreeNode<T>;
}

constructor(props?: ITreeNodeProps<T>, context?: any) {
Copy link
Contributor

Choose a reason for hiding this comment

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

remove

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The code won't compiled without, because of the following function:
public static ofType() {
return TreeNode as new () => TreeNode;
}

It is necessary....

Copy link
Contributor

Choose a reason for hiding this comment

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

oh snap! yeah it does fail. but that's just a typings issue.

props? in constructor is actually wrong--it goes against React's types and will fail if strictNullChecks is enabled (it is disabled in blueprint).

i'll resolve that in all instances later 👍

@giladgray giladgray merged commit cc106a0 into palantir:develop Mar 7, 2018
This was referenced Mar 7, 2018
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