-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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] Validation improvements #1587
Conversation
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.
Quick thoughts/questions.
@@ -524,6 +524,8 @@ export class Table extends AbstractComponent<ITableProps, ITableState> { | |||
} | |||
|
|||
public componentWillReceiveProps(nextProps: ITableProps) { | |||
super.componentWillReceiveProps(nextProps); |
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.
#whoops
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.
Womp
// the second part of this conditional will never be true, but it | ||
// informs the TS compiler that we won't be invoking | ||
// childType.prototype on a "string" element. | ||
if (typeof child === "string" || typeof childType === "string") { |
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.
Janky, but it was throwing an error before I added the typeof child === "string"
check. Turns out typeof childType === undefined
for strings, so the check wasn't working as expected before.
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.
...so it's a... typeguard? That's... weird. I am confused as to how this could possibly be working. But... ok?
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.
typeof childType === "string"
is the typeguard, yeah. But it never returns true
. @giladgray, do you know a way out of this comical quagmire?
} else { | ||
const isColumn = childType.prototype === Column.prototype || Column.prototype.isPrototypeOf(childType); | ||
if (!isColumn) { | ||
console.warn(Errors.TABLE_NON_COLUMN_CHILDREN_WARNING); | ||
throw new Error(Errors.TABLE_NON_COLUMN_CHILDREN_WARNING); |
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.
Is there ever a case where we'd want to let people wrap child <Column>
s with a thing? If not, would prefer this to be an Error
.
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.
I think you're probably right, @adidahiya might know if the other ever comes up? Not sure.
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.
do we really need to validate the react children? what does this buy us? what's the harm in being lenient? please keep #1108 in mind; enforcing constraints on React children in typescript usually gets in the way more often than it helps.
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.
table.tsx
accesses props.children
expecting it to be an array of <Column>s
(e.g. in Table.getColumnProps
). If that accessing fails, the error message is somewhat convoluted; throwing a clear error from validateProps
would be more helpful.
Only reservation is that maybe there are cases when people would want to compose a basic <Column>
into something else they'd want to provide as a direct child of Table
? In that case, a duck-typing approach would seem preferable (i.e. as long as the child in question supports the Column
API, we don't care).
I've never heard of anyone doing the above customization, so I'm including the error check as a result of my first point. ^ Thoughts?
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.
for now I'm fine with enforcing Column
to be a direct child of Table
-- as you said we haven't seen the wrapping component use case come up. makes sense to have a better error message and halt execution since the table won't render correctly. let's get to #1108 soon for 2.0.
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.
👍
Move warnings to bottomPreview: documentation | table |
@@ -524,6 +524,8 @@ export class Table extends AbstractComponent<ITableProps, ITableState> { | |||
} | |||
|
|||
public componentWillReceiveProps(nextProps: ITableProps) { | |||
super.componentWillReceiveProps(nextProps); |
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.
Womp
// the second part of this conditional will never be true, but it | ||
// informs the TS compiler that we won't be invoking | ||
// childType.prototype on a "string" element. | ||
if (typeof child === "string" || typeof childType === "string") { |
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.
...so it's a... typeguard? That's... weird. I am confused as to how this could possibly be working. But... ok?
} else { | ||
const isColumn = childType.prototype === Column.prototype || Column.prototype.isPrototypeOf(childType); | ||
if (!isColumn) { | ||
console.warn(Errors.TABLE_NON_COLUMN_CHILDREN_WARNING); | ||
throw new Error(Errors.TABLE_NON_COLUMN_CHILDREN_WARNING); |
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.
I think you're probably right, @adidahiya might know if the other ever comes up? Not sure.
Adding @adidahiya for CR because you've used the |
Fixes #1371
Checklist
Changes proposed in this pull request:
Table
now validates props on mount and on update.Table
now validates props as follows (assuming each prop involved is defined):numRows < 0
numFrozenRows < 0
numFrozenColumns < 0
numRows !== rowHeights.length
numColumns !== columnWidths.length
non-<Column> child
(*)numFrozenRows > numRows
(changed the message to mention that we'll clamp for you)numFrozenColumns > numColumns
(same)Reviewers should focus on:
<Column>
children, so I figure we might as well just throw a clear error at the outset.Screenshot