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 data table component #141

Merged
merged 21 commits into from
Jun 28, 2018
Merged

Add data table component #141

merged 21 commits into from
Jun 28, 2018

Conversation

andrewpye
Copy link
Member

@andrewpye andrewpye commented Jun 22, 2018

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:
polaris-data-table-footer

Data table with sortable columns (when the sorting updates without clicking it's because I pressed Enter while the column heading was focussed):
polaris-data-table-sortable

@andrewpye andrewpye self-assigned this Jun 22, 2018
@andrewpye andrewpye requested review from vladucu and tomnez June 22, 2018 14:58
@andrewpye
Copy link
Member Author

@andrewpye andrewpye changed the base branch from master to enhancement/support-react-style-content-rendering June 25, 2018 14:49
Copy link
Contributor

@tomnez tomnez left a 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}
Copy link
Contributor

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 @types in these files

Copy link
Member Author

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...

Copy link
Contributor

@tomnez tomnez Jun 26, 2018

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 😉

Copy link
Member Author

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 🤷‍♂️

Copy link
Contributor

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.

Copy link
Member

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.
Copy link
Contributor

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.
Copy link
Contributor

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?

Copy link
Member Author

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.

{{action onSort}}
onkeydown={{action "onKeyDown"}}
>
{{#if (eq contentType "text")}}

This comment was marked as resolved.

This comment was marked as resolved.

}}

{{#each columnVisibilityData as |column|}}
<div class="Polaris-DataTable__Pip {{if column.isVisible "Polaris-DataTable__Pip--visible"}}"></div>
Copy link
Contributor

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.

Copy link
Member Author

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 😉

Copy link
Member

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) {
Copy link
Contributor

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,
Copy link
Contributor

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.
Copy link
Contributor

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?
Copy link
Contributor

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.

Copy link
Member Author

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...

Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member Author

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 😬

@andrewpye andrewpye changed the base branch from enhancement/support-react-style-content-rendering to master June 26, 2018 06:35
@vladucu
Copy link
Member

vladucu commented Jun 26, 2018

sorry for the delay on this, getting to it in a bit...

Copy link
Member

@vladucu vladucu left a 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}
Copy link
Member

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}}
Copy link
Member

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"}}">
Copy link
Member

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"}}">
Copy link
Member

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>
Copy link
Member

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};
Copy link
Member

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];
Copy link
Member

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?

Copy link
Member Author

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?
Copy link
Member

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(),
Copy link
Member

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

Copy link
Member Author

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';
Copy link
Member

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

Copy link
Member

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

@andrewpye
Copy link
Member Author

@vladucu changes pushed, ready for 👀 pt. deux 😅

@andrewpye andrewpye requested a review from vladucu June 27, 2018 13:21
@andrewpye andrewpye requested a review from tomnez June 27, 2018 13:21
@andrewpye
Copy link
Member Author

(tests are currently failing on Travis due to package issues 😞They all pass locally!)

Copy link
Member

@vladucu vladucu left a 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()}`);
Copy link
Member

Choose a reason for hiding this comment

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

nit: spaces

@andrewpye andrewpye merged commit 0aef05d into master Jun 28, 2018
@andrewpye andrewpye deleted the add-data-table-component branch June 28, 2018 12:06
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.

None yet

3 participants