-
Notifications
You must be signed in to change notification settings - Fork 6
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 data table component #141
Conversation
…sponsiveness and testing
73062c9
to
3c821b0
Compare
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.
This is awesome! Few questions and comments, but overall this is great and I'm excited to finally get this in 🕺
|
||
/** | ||
* @property fixed | ||
* @type {boolean} |
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.
You have a mix of uppercase and lowercase @type
s in these files
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.
Yeah... and across the whole addon 😬 If we ever get the stage of using the JSDoc to generate documentation we should definitely standardise this, but at this point I'm not that fussed. Curious as to @vladucu's thoughts on this...
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.
He'd probably say something like this 😉
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.
Yeah maybe 😛 We currently have 22 {Boolean}
s and 54 {boolean}
s, so clearly we'll need to tidy those up at some point 😬 I think it's a big enough job to be done separately from this PR 🤷♂️
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.
Yeah I just meant change the files in this PR, not across the addon. No reason to continue a bad habit just because it's already been done elsewhere.
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 don't really care much about these at this point since we don't use them....but going forward we could try to add them appropriately - uppercased?
// to the `get` helper. If we stop supporting | ||
// Ember 2.12, we can remove this helper and | ||
// replace its usages with the existing `get` | ||
// helper. |
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.
👍
layout, | ||
|
||
/** | ||
* TODO: make this support passing a component to render instead of just text/numbers. |
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 this note still relevant since we are using {{render-content ...}}
in this branch now?
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.
Good catch, I rushed through adding render-content
yesterday afternoon and missed this 👍
aria-sort={{sortDirection}} | ||
aria-label={{sortAccessibilityLabel}} | ||
tabindex="0" | ||
{{action onSort}} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
{{action onSort}} | ||
onkeydown={{action "onKeyDown"}} | ||
> | ||
{{#if (eq contentType "text")}} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
}} | ||
|
||
{{#each columnVisibilityData as |column|}} | ||
<div class="Polaris-DataTable__Pip {{if column.isVisible "Polaris-DataTable__Pip--visible"}}"></div> |
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.
Maybe single-quote the inner string for slightly easier readability? No biggie if we prefer double quotes even for nested strings in templates, but just a thought.
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.
Fair point, never single-quoted in template files before. I'm OK with this as is, but if both you and @vladucu would prefer it changed I'm happy to change it, no biggie as you say 😉
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've usually used single-quotes in cases like this just to avoid confusion and be easier to read
assert.ok(fifthHeadingCell.classList.contains('Polaris-DataTable__Cell--sorted')); | ||
}); | ||
|
||
test('it accepts both text and component definitions as cell contents', async function(assert) { |
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.
💯 💯 💯
* @type {boolean} | ||
* @public | ||
*/ | ||
presentational: false, |
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.
There are some inconsistencies in these files on whether or not there's a @default
added - I think we want @default
notation for any non-null attribute, yes?
}, | ||
|
||
handleResize() { | ||
// This is needed to replicate the React implementation's `@debounce` decorator. |
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.
👍
previousColumn.leftEdge < 10 ? 0 : previousColumn.leftEdge; | ||
} | ||
|
||
// TODO: use run loop instead of `requestAnimationFrame` here? |
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.
Seems like requestAnimationFrame
is just an overkill way of quickly calculating precise position values of columns? I don't know if swapping for run loop would accomplish whatever the intention of requestAnimationFrame
here is, maybe just leave as-is unless you're certain that we need to throw this into one of the run loop cycles.
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.
My understanding is that requestAnimationFrame
helps prevent jankiness on scrolling, resizing etc. by limiting the amount of work done to only that which can be fitted between two consecutive frame renders. With this in mind, using it here makes some kind of sense, although I'm slightly confused as to why it's not being used anywhere else (I'd expect the resize handler to be a candidate for its use, for example).
That being said, I'm not sure if using it directly here creates the possibility of interfering with the Ember run loop. The interesting-looking ember-run-raf
addon seems to be advocating "using run.scheduleOnce
+ requestAnimationFrame
" in combination, so maybe we should be doing that combo here, 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.
Oh wow I didn't realize there was an addon that tied the two together. If it's owned/authored by runspired then I trust it, but again for this purpose I don't think it's really an urgent need. It's up to you if you want to experiment with it but I think I'm fine to leave it as-is.
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.
Yeah agreed, that guy knows what he's doing (though I bet he wishes he was @vladucu 😉)! I wasn't intending to pull in the addon here though, just found it the other day and thought it was interesting.
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.
add a note here maybe to check ember-run-raf
when testing this in the real world?
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.
From what I can see, ember-run-raf
changes the entire run loop to use requestAnimationFrame
rather than adding the option to e.g. schedule on an animation frame queue, so probs not something we want to pull in to the host app 😬
sorry for the delay on this, getting to it in a bit... |
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.
this looks pretty nice!
a couple of small comments, mostly I'd like us to clean up event handling before this goes out
|
||
/** | ||
* @property fixed | ||
* @type {boolean} |
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 don't really care much about these at this point since we don't use them....but going forward we could try to add them appropriately - uppercased?
style={{style}} | ||
role="button" | ||
aria-sort={{sortDirection}} | ||
aria-label={{sortAccessibilityLabel}} |
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.
need to define sortAccessibilityLabel
, check here for their locale
onkeydown={{action "onKeyDown"}} | ||
> | ||
{{#if (eq contentType "text")}} | ||
<span class="Polaris-DataTable__Heading {{if (eq contentType "text") "Polaris-DataTable__Heading--left"}}"> |
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.
this is already in a if (eq contentType "text")
, can we just add "Polaris-DataTable__Heading--left"
class without any condition?
</span> | ||
</span> | ||
{{else}} | ||
<span class="Polaris-DataTable__Heading {{if (eq contentType "text") "Polaris-DataTable__Heading--left"}}"> |
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.
and here being in the if (eq contentType "text")
else branch, don't add "Polaris-DataTable__Heading--left"
at all
}} | ||
|
||
{{#each columnVisibilityData as |column|}} | ||
<div class="Polaris-DataTable__Pip {{if column.isVisible "Polaris-DataTable__Pip--visible"}}"></div> |
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've usually used single-quotes in cases like this just to avoid confusion and be easier to read
index, | ||
); | ||
} | ||
return {leftEdge, rightEdge, isVisible}; |
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.
ni: spaces
|
||
if (!truncate) { | ||
return (heights = rows.map((row) => { | ||
let fixedCell = row.children[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.
react uses childNodes
, any reason we don't follow?
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.
Yep, childNodes
includes a bunch of extra text
nodes in Ember land which aren't present in the React world (spent a lil while tracking down why this wasn't behaving properly and that turned out to be the cause) 🤷♂️
previousColumn.leftEdge < 10 ? 0 : previousColumn.leftEdge; | ||
} | ||
|
||
// TODO: use run loop instead of `requestAnimationFrame` here? |
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.
add a note here maybe to check ember-run-raf
when testing this in the real world?
* @type {HTMLElement} | ||
* @private | ||
*/ | ||
table: volatileElementLookup('.Polaris-DataTable__Table').readOnly(), |
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 don't think these element lookups need to be volatile
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 guess you're right actually 👍
import { setupRenderingTest } from 'ember-qunit'; | ||
import { render } from '@ember/test-helpers'; | ||
import hbs from 'htmlbars-inline-precompile'; | ||
import { findAll, find } from 'ember-native-dom-helpers'; |
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.
we should use the new find, findAll from @ember/test-helpers
....we can probably start deprecating native-dom helpers
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.
not saying this should not go out because of that^
we should also use qunit-dom for assertion, from what I've seen much nicer error messages
@vladucu changes pushed, ready for 👀 pt. deux 😅 |
(tests are currently failing on Travis due to package issues 😞They all pass locally!) |
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.
👏
@@ -188,6 +209,17 @@ export default Component.extend({ | |||
return `caret-${ sortDirection === 'ascending' ? 'up' : 'down' }`; | |||
}).readOnly(), | |||
|
|||
updateAccessibilityLabel() { | |||
let cellElement = document.querySelector(`#${ this.get('cellElementId') }`); | |||
this.set('sortAccessibilityLabel', `Sort by ${cellElement.textContent.trim().toLowerCase()}`); |
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: spaces
Depends on #142 in order to be able to render arbitrary components in table cells.
Adds full implementation of the Polaris data table component:
Reproducing the demos on the Shopify component documentation page:
Data table with footer:
Data table with sortable columns (when the sorting updates without clicking it's because I pressed
Enter
while the column heading was focussed):