-
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 preferredPosition
to polaris-popover
#117
Conversation
import layout from '../templates/components/polaris-popover'; | ||
|
||
const { ViewUtils } = Ember; |
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.
Hax, suggested by @andrewpye - emberjs/rfcs#168 (comment)
I don't believe there is a way to import these utils using the ES6 modules syntax.
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.
Just leaving some comments for now to start some discussion, although this does look alright IMO
addon/components/polaris-popover.js
Outdated
* @default null | ||
* TODO: not implemented | ||
*/ | ||
preferredPosition: null, |
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 should probably default to below
to match the React implementation
addon/components/polaris-popover.js
Outdated
// and set when the user opens the popover. | ||
|
||
return null; | ||
}), |
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.
.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.
This gets set
by the onOpen
action if the position is set to "mostSpace"
, so it can't be 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.
Hmm... seems like an unlikely scenario, but set
ting this in onOpen
will mean that if the host app passes in a dynamic preferredPosition
and that value changes from 'mostSpace' after first open, the popover won't honour that change because onOpen
will overwrite the CP behaviour here. You could add an explicit setter to this CP, and that way I think that (really tiny) edge case would be avoided...
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.
verticalPosition
is still a CP, so if preferredPosition
dynamically changes, it will re-set verticalPosition
to the new value, and then when onOpen
runs it will not compute a new value for verticalPosition
because it only computes a new value if preferredPosition
is set to "mostSpace"
.
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.
After set
ting verticalPosition
on line 161, my understanding is that verticalPosition
will no longer be a CP - the set
will replace the entire CP with the literal value that you're setting it to, unless the CP has its own set
defined as well. Think of it like this, where someObject
is the result of the computed
call:
... other props...
myComputed: someObject,
... other stuff...
If you then this.set('myComputed', 'something else')
, you'll replace someObject
with the new string literal. The CP "contained" in someObject
will be torn down, and will no longer be computed on dependency changes. From then on, this.get('myComputed')
will always return 'something else'
.
You can work around this by defining the CP as
myComputed: computed('dep1', 'dep2', {
get() {
return 'whatever';
},
set(key, value) {
return value;
}
),
The set
part ensures that the CP remains after a this.set('myComputed', 'something else')
, and the value will still update after dep1
or dep2
change...
addon/components/polaris-popover.js
Outdated
|
||
if (preferredPosition === 'below') { | ||
return preferredPosition; | ||
} |
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.
Why not bundle these two into a single if
-statement?
addon/components/polaris-popover.js
Outdated
let component; | ||
|
||
// Hack to get the component's container | ||
// element since this component uses `tagName: ''` |
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 link here to the RFC I linked you to so we know where this came from in the future 👍
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.
(unless of course @vladucu knows any better way to do 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.
good with me for now, ideally I think we should investigate refactoring this at some point and not using ember-basic-dropdown
addon/components/polaris-popover.js
Outdated
let preferredPosition = this.get('preferredPosition'); | ||
|
||
if (preferredPosition === 'mostSpace') { | ||
this.set('verticalPosition', this.mostVerticalSpace()); |
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 a huge fan of the naming of mostVerticalSpace
as a method - it sounds more like a property since there's no verb in the name. How about getMostVerticalSpace
or making it a volatile
CP and keeping the mostVerticalSpace
name?
@@ -6,7 +6,7 @@ | |||
component](https://polaris.shopify.com/components/overlays/popover). This component uses [`ember-basic-dropdown`](https://github.com/cibernox/ember-basic-dropdown) to implement popover functionality. Note that the usage is slightly different from the React implementation so please pay attention to the examples below. | |||
|
|||
|
|||
**NOTE:** _the `preferredPosition`, `active`, `activatorWrapper`, `preventAutofocus` and `onClose` properties are currently unimplemented._ | |||
**NOTE:** _the `active`, `activatorWrapper`, `preventAutofocus` and `onClose` properties are currently unimplemented._ |
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.
👍
@@ -101,3 +103,29 @@ test('it renders the correct HTML with sectioned attribute', function(assert) { | |||
assert.equal(popoverSections.length, 1, 'renders one popover section'); | |||
assert.equal(popoverSections[0].textContent.trim(), 'This is some sectioned popover content', 'popover section contains the correct content'); | |||
}); | |||
|
|||
skip('it renders the correct HTML with `prefferedPosition` attribute', 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.
@vladucu what are your thoughts on this test? It's skip
ped at the moment because it's testing things rendered outside the test div - we can either keep it here and skip
it, or maybe look into using document.querySelector
etc. instead of the test helpers to retrieve the necessary elements?
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.
yes, I'd lean towards using document.querySelector
(or whatever works) and not skip the test if possible
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'll see if document.querySelector
works
@@ -101,3 +103,29 @@ test('it renders the correct HTML with sectioned attribute', function(assert) { | |||
assert.equal(popoverSections.length, 1, 'renders one popover section'); | |||
assert.equal(popoverSections[0].textContent.trim(), 'This is some sectioned popover content', 'popover section contains the correct content'); | |||
}); | |||
|
|||
skip('it renders the correct HTML with `prefferedPosition` attribute', 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.
Also @tomnez you've got a typo all over the place with preffered
😛
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.
@vladucu @andrewpye updated - also I left the |
@andrewpye updated! And thanks for the detailed explanations 👍 |
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.
Think this is good, one single-quote => double-quote change to make then 🚢 🔥
@@ -1,4 +1,6 @@ | |||
{{#basic-dropdown | |||
verticalPosition=verticalPosition | |||
onOpen=(action 'onOpen') |
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.
Double-quotes in template files pls 😉
@@ -339,7 +339,7 @@ test('it does not fire actions when disabled days are clicked', function(assert) | |||
year: YEAR, | |||
selected: null, | |||
disableDatesAfter: DISABLE_AFTER, | |||
onChange: (selected) => { | |||
onChange: () => { |
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 sure you need the colon here actually
|
||
const contentBelow = document.querySelector(popoverContentBelowSelector); | ||
assert.ok(contentBelow, 'renders popover content below the trigger'); | ||
}); |
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.
Love that you got this working 😍
e4d261e
to
ae90dda
Compare
@andrewpye updated |
Overview
This adds the
preferredPosition
to the polaris-popover component.It basically translates the user-provided
preferredPosition
value into averticalPosition
attribute since we use ember-basic-dropdown as our popover component under the hood.Test for this is skipped because ember-basic-dropdown uses ember wormhole for the popover content, which renders content outside of the ember testing container.