Skip to content

Commit

Permalink
fix(positioning): fix errors on invalid position (#5212)
Browse files Browse the repository at this point in the history
* fix(positioning): fix errors on invalid position
  • Loading branch information
Domainv authored May 17, 2019
1 parent bd9c72e commit e790196
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export class BsDatepickerContainerComponent extends BsDatepickerAbstractComponen
flip: {
enabled: this._config.adaptivePosition
}
}
},
allowedPositions: ['top', 'bottom']
});

this.isOtherMonthsActive = this._config.selectFromOtherMonth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ export class BsDaterangepickerContainerComponent extends BsDatepickerAbstractCom
flip: {
enabled: this._config.adaptivePosition
}
}
},
allowedPositions: ['top', 'bottom']
});

this.containerClass = this._config.containerClass;
Expand Down
2 changes: 1 addition & 1 deletion src/dropdown/bs-dropdown.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export class BsDropdownDirective implements OnInit, OnDestroy {
(typeof this.dropup !== 'undefined' && this.dropup);
this._state.direction = _dropup ? 'up' : 'down';
const _placement =
this.placement || (_dropup ? 'top left' : 'bottom left');
this.placement || (_dropup ? 'top start' : 'bottom start');

// show dropdown
this._dropdown
Expand Down
1 change: 1 addition & 0 deletions src/positioning/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ export interface Options {
enabled: boolean;
};
};
allowedPositions?: string[];
}
5 changes: 1 addition & 4 deletions src/positioning/modifiers/flip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ export function flip(data: Data): Data {
const target = data.instance.target;
const host = data.instance.host;

const adaptivePosition = variation
? computeAutoPlacement('auto', offsetsHost, target, host, ['top', 'bottom'])
: computeAutoPlacement('auto', offsetsHost, target, host);

const adaptivePosition = computeAutoPlacement('auto', offsetsHost, target, host, data.options.allowedPositions);
const flipOrder = [placement, adaptivePosition];

/* tslint:disable-next-line: cyclomatic-complexity */
Expand Down
20 changes: 17 additions & 3 deletions src/positioning/modifiers/initData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ export function initData(
): Data {

const hostElPosition = getReferenceOffsets(targetElement, hostElement);

if (!position.match(/^(auto)*\s*(left|right|top|bottom)*$/)
&& !position.match(/^(left|right|top|bottom)*\s*(start|end)*$/)) {
/* tslint:disable-next-line: no-parameter-reassignment */
position = 'auto';
}

const placementAuto = !!position.match(/auto/g);

// support old placements 'auto left|right|top|bottom'
let placement = !!position.match(/auto\s(left|right|top|bottom)/g)
? position.split(' ')[1] || ''
let placement = position.match(/auto\s(left|right|top|bottom)/)
? position.split(' ')[1] || 'auto'
: position;

const targetOffset = getTargetOffsets(targetElement, hostElPosition, placement);
placement = computeAutoPlacement(placement, hostElPosition, targetElement, hostElement);

placement = computeAutoPlacement(
placement,
hostElPosition,
targetElement,
hostElement,
options ? options.allowedPositions : undefined
);

return {
options,
Expand Down
5 changes: 4 additions & 1 deletion src/positioning/modifiers/preventOverflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ export function preventOverflow(data: Data) {
? 'primary'
: 'secondary';

data.offsets.target = { ...data.offsets.target, ...(check as any)[side](placement) };
data.offsets.target = {
...data.offsets.target,
...(check as any)[side](placement)
};

});

Expand Down
6 changes: 3 additions & 3 deletions src/positioning/modifiers/shift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export function shift(data: Data): Data {
const measurement = isVertical ? 'width' : 'height';

const shiftOffsets = {
left: { [side]: host[side] },
right: {
[side]: host[side] + host[measurement] - host[measurement]
start: { [side]: host[side] },
end: {
[side]: host[side] + host[measurement] - target[measurement]
}
};

Expand Down
17 changes: 15 additions & 2 deletions src/positioning/ng-positioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import { Renderer2 } from '@angular/core';

import { getReferenceOffsets, setAllStyles } from './utils';
import { getOffsets, getReferenceOffsets, updateContainerClass, setStyles } from './utils';

import { arrow, flip, preventOverflow, shift, initData } from './modifiers';
import { Data, Offsets, Options } from './models';
Expand Down Expand Up @@ -54,5 +54,18 @@ export function positionElements(
options
);

setAllStyles(data, renderer);
const offsets = getOffsets(data);

setStyles(targetElement, {
'will-change': 'transform',
top: '0px',
left: '0px',
transform: `translate3d(${offsets.left}px, ${offsets.top}px, 0px)`
}, renderer);

if (data.instance.arrow) {
setStyles(data.instance.arrow, data.offsets.arrow, renderer);
}

updateContainerClass(data, renderer);
}
21 changes: 13 additions & 8 deletions src/positioning/utils/computeAutoPlacement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function computeAutoPlacement(
refRect: Offsets,
target: HTMLElement,
host: HTMLElement,
allowedPositions: any[] = ['top', 'left', 'bottom', 'right'],
allowedPositions: any[] = ['top', 'bottom', 'right', 'left'],
boundariesElement = 'viewport',
padding = 0
) {
Expand Down Expand Up @@ -52,22 +52,27 @@ export function computeAutoPlacement(
.sort((a, b) => b.area - a.area);

let filteredAreas: any[] = sortedAreas.filter(
({ width, height }) =>
width >= target.clientWidth && height >= target.clientHeight
({ width, height }) => {
return width >= target.clientWidth
&& height >= target.clientHeight;
}
);

filteredAreas = allowedPositions
.reduce((obj, key) => {
return { ...obj, [key]: filteredAreas[key] };
}, {});
filteredAreas = filteredAreas.filter((position: any) => {
return allowedPositions
.some((allowedPosition: string) => {
return allowedPosition === position.key;
});
});

const computedPlacement: string = filteredAreas.length > 0
? filteredAreas[0].key
: sortedAreas[0].key;

const variation = placement.split(' ')[1];

target.className = target.className.replace(/auto/g, computedPlacement);
// for tooltip on auto position
target.className = target.className.replace(/bs-tooltip-auto/g, `bs-tooltip-${computedPlacement}`);

return computedPlacement + (variation ? `-${variation}` : '');
}
2 changes: 1 addition & 1 deletion src/positioning/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export { getWindowSizes } from './getWindowSizes';
export { isFixed } from './isFixed';
export { isModifierEnabled } from './isModifierEnabled';
export { isNumeric } from './isNumeric';
export { setAllStyles } from './setAllStyles';
export { updateContainerClass } from './updateContainerClass';
export { setStyles } from './setStyles';
71 changes: 0 additions & 71 deletions src/positioning/utils/setAllStyles.ts

This file was deleted.

35 changes: 35 additions & 0 deletions src/positioning/utils/updateContainerClass.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Update class for the given popper
*/
import { Renderer2 } from '@angular/core';
import { Data } from '../models';

export function updateContainerClass(data: Data, renderer?: Renderer2): void {
const target = data.instance.target;

let containerClass = target.className;

if (data.placementAuto) {
containerClass = containerClass.replace(/bs-popover-auto/g, `bs-popover-${data.placement}`);
containerClass = containerClass.replace(/bs-tooltip-auto/g, `bs-tooltip-${data.placement}`);
containerClass = containerClass.replace(/\sauto/g, ` ${data.placement}`);

if (containerClass.indexOf('popover') !== -1 && containerClass.indexOf('popover-auto') === -1) {
containerClass += ' popover-auto';
}

if (containerClass.indexOf('tooltip') !== -1 && containerClass.indexOf('tooltip-auto') === -1) {
containerClass += ' tooltip-auto';
}
}

containerClass = containerClass.replace(/left|right|top|bottom/g, `${data.placement.split(' ')[0]}`);

if (renderer) {
renderer.setAttribute(target, 'class', containerClass);

return;
}

target.className = containerClass;
}
5 changes: 3 additions & 2 deletions src/typeahead/typeahead.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,15 @@ export class TypeaheadDirective implements OnInit, OnDestroy {
flip: {
enabled: this.adaptivePosition
}
}
},
allowedPositions: ['top', 'bottom']
});

this._typeahead
.attach(TypeaheadContainerComponent)
// todo: add append to body, after updating positioning service
.to(this.container)
.position({attachment: `${this.dropup ? 'top' : 'bottom'} left`})
.position({attachment: `${this.dropup ? 'top' : 'bottom'} start`})
.show({
typeaheadRef: this,
placement: this.placement,
Expand Down

0 comments on commit e790196

Please sign in to comment.