Skip to content

Commit

Permalink
Merge pull request #60 from ChrisCinelli/fixPosition
Browse files Browse the repository at this point in the history
When the space is not enough to contain the pop up use the best fit
  • Loading branch information
jasonkuhrt committed Jan 7, 2016
2 parents 9201bdc + c373659 commit 60d7099
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
2 changes: 1 addition & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ const Popover = createClass({
!this.containerEl.contains(event.target) &&
!this.targetEl.contains(event.target)
)
if (isOuterAction) this.props.onOuterAction()
if (isOuterAction) this.props.onOuterAction(event)
},
untrackPopover () {
clearInterval(this.checkLayoutInterval)
Expand Down
34 changes: 26 additions & 8 deletions lib/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const getPreferenceType = (preference) => (
/* Dimension Fit Checks */

const fitWithinChecker = (dimension) => (domainSize, itemSize) => (
domainSize[dimension] > itemSize[dimension]
domainSize[dimension] >= itemSize[dimension]
)

const doesWidthFitWithin = fitWithinChecker(`w`)
Expand All @@ -160,10 +160,8 @@ const createPreferenceError = (givenValue) => (



/* Algorithm for picking the best fitting zone for popover. The current technique will loop through all zones picking the last one that fits. If
none fit the last one is selected.
TODO In the case that none fit we should pick the least-not-fitting zone. */
/* Algorithm for picking the best fitting zone for popover. The current technique will loop through all zones picking the last one that fits.
In the case that none fit we should pick the least-not-fitting zone. */

const pickZone = (opts, frameBounds, targetBounds, size) => {
const t = targetBounds
Expand All @@ -174,11 +172,21 @@ const pickZone = (opts, frameBounds, targetBounds, size) => {
{ side: `end`, standing: `below`, flow: `column`, order: 1, w: f.x2, h: (f.y2 - t.y2) },
{ side: `start`, standing: `left`, flow: `row`, order: -1, w: t.x, h: f.y2 },
]


/* Order the zones by the amount of popup that would be cut out if that zone is used.
The first one in the array is the one that cuts the least amount.
const area = size.w * size.h // Popup area is constant and it does not change the order
*/
zones.forEach((z) => {
z.cutOff = /* area */ - Math.max(0, Math.min(z.w,size.w)) * Math.max(0, Math.min(z.h,size.h))
})
zones.sort((a,b) => a.cutOff - b.cutOff)

const availZones = zones.filter((zone) => (
doesFitWithin(zone, size)
))

/* If a place is required pick it from the available zones if possible. */

if (opts.place) {
Expand All @@ -190,17 +198,27 @@ const pickZone = (opts, frameBounds, targetBounds, size) => {

/* If the preferred side is part of the available zones, use that otherwise
pick the largest available zone. If there are no available zones, pick the
largest zone. TODO: logic that executes picking based on largest option. */
largest zone. */

if (opts.preferPlace) {
const preferenceType = getPreferenceType(opts.preferPlace)
if (!preferenceType) throw createPreferenceError(opts.preferPlace)

// Try to fit first in zone where the pop up fit completely
const preferredAvailZones = availZones.filter((zone) => (
zone[preferenceType] === opts.preferPlace
))
if (preferredAvailZones.length) return preferredAvailZones[0]

// If there are not areas where the pop up fit completely, it uses the prefered ones
// in order from the one the fit better
const preferredZones = zones.filter((zone) => (
zone[preferenceType] === opts.preferPlace
))
if (preferredZones.length) return preferredZones[0]
}

// Return a zone that fit completely or the one that fit the best
return availZones.length ? availZones[0] : zones[0]
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"babel-core": "^6.3.15",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"bluebird": "^3.0.5",
"bootstrap-webpack-plugin": "^0.3.0",
"chai": "^3.2.0",
Expand Down

0 comments on commit 60d7099

Please sign in to comment.