Skip to content

Commit

Permalink
fix(ui): popover margins offsets fix (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
32penkin authored Apr 25, 2019
1 parent a08f8f2 commit 1e3167b
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 126 deletions.
19 changes: 14 additions & 5 deletions src/framework/ui/popover/popover.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
Frame,
Placement,
Placements,
MarginOffsets,
getMarginOffsets,
} from './type';

interface PopoverProps {
Expand All @@ -52,6 +54,7 @@ export class Popover extends React.Component<Props, State> {
static defaultProps: Partial<Props> = {
placement: PLACEMENT_DEFAULT.rawValue,
visible: false,
scrollOffset: 0,
};

public state: State = {
Expand All @@ -69,11 +72,17 @@ export class Popover extends React.Component<Props, State> {
}

public componentDidUpdate(prevProps: Props, prevState: State): void {
const { visible, placement, onRequestClose } = this.props;
const {
visible,
placement,
onRequestClose,
children,
} = this.props;

if (prevProps.visible !== visible) {
if (visible) {
const { origin: popoverPosition } = this.getPopoverFrame(placement);
const marginOffsets: MarginOffsets = getMarginOffsets(children.props.style);
const { origin: popoverPosition } = this.getPopoverFrame(placement, marginOffsets);
const style: FlexStyle = {
left: popoverPosition.x,
top: popoverPosition.y,
Expand Down Expand Up @@ -102,13 +111,13 @@ export class Popover extends React.Component<Props, State> {
};
};

private getPopoverFrame = (rawPlacement: string | Placement): Frame => {
private getPopoverFrame = (rawPlacement: string | Placement, offsets: MarginOffsets): Frame => {
const { layout } = this.state;
const { [TAG_CONTENT]: popoverFrame, [TAG_CHILD]: childFrame } = layout;

const placement: Placement = Placements.parse(rawPlacement, PLACEMENT_DEFAULT);

return placement.frame(popoverFrame, childFrame);
return placement.frame(popoverFrame, childFrame, offsets);
};

private onMeasure = (layout: MeasureResult) => {
Expand All @@ -118,7 +127,7 @@ export class Popover extends React.Component<Props, State> {
private renderPopoverElement = (children: React.ReactElement<any>, style: StyleType): MeasuringElement => {
const { placement, ...derivedProps } = this.props;

const measuringProps: MeasuringElementProps = { tag: TAG_CONTENT };
const measuringProps: MeasuringElementProps = { tag: TAG_CONTENT, scrollOffset: this.props.scrollOffset };

const popoverPlacement: Placement = Placements.parse(placement, PLACEMENT_DEFAULT);
const indicatorPlacement: Placement = popoverPlacement.reverse();
Expand Down
152 changes: 80 additions & 72 deletions src/framework/ui/popover/type.spec.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,50 @@
import {
Frame,
MarginOffsets,
Placement,
Placements,
} from './type';

describe('@type: popover model checks', () => {

const marginOffsets: MarginOffsets = {
offsetLeft: 2,
offsetTop: 2,
offsetRight: 2,
offsetBottom: 2,
};

describe('* frame', () => {

const lhsFrame: Frame = new Frame(2, 2, 2, 2);
const rhsFrame: Frame = new Frame(4, 4, 2, 2);

it('* left of', () => {
const { origin: { x, y } } = rhsFrame.leftOf(lhsFrame);
const { origin: { x, y } } = rhsFrame.leftOf(lhsFrame, marginOffsets.offsetLeft);

expect(x).toEqual(0);
expect(x).toEqual(2);
expect(y).toEqual(4);
});

it('* top of', () => {
const { origin: { x, y } } = rhsFrame.topOf(lhsFrame);
const { origin: { x, y } } = rhsFrame.topOf(lhsFrame, marginOffsets.offsetTop);

expect(x).toEqual(4);
expect(y).toEqual(0);
expect(y).toEqual(2);
});

it('* right of', () => {
const { origin: { x, y } } = rhsFrame.rightOf(lhsFrame);
const { origin: { x, y } } = rhsFrame.rightOf(lhsFrame, marginOffsets.offsetRight);

expect(x).toEqual(4);
expect(x).toEqual(2);
expect(y).toEqual(4);
});

it('* bottom of', () => {
const { origin: { x, y } } = rhsFrame.bottomOf(lhsFrame);
const { origin: { x, y } } = rhsFrame.bottomOf(lhsFrame, marginOffsets.offsetBottom);

expect(x).toEqual(4);
expect(y).toEqual(4);
expect(y).toEqual(2);
});

it('* center horizontal of', () => {
Expand All @@ -61,87 +69,87 @@ describe('@type: popover model checks', () => {
const rhsFrame: Frame = new Frame(6, 6, 2, 2);

it('* left', () => {
const { origin: { x, y } } = Placements.LEFT.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.LEFT.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(0);
expect(x).toEqual(2);
expect(y).toEqual(3);
});

it('* left start', () => {
const { origin: { x, y } } = Placements.LEFT_START.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.LEFT_START.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(0);
expect(y).toEqual(2);
expect(x).toEqual(2);
expect(y).toEqual(4);
});

it('* left end', () => {
const { origin: { x, y } } = Placements.LEFT_END.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.LEFT_END.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(0);
expect(y).toEqual(4);
expect(x).toEqual(2);
expect(y).toEqual(2);
});

it('* top', () => {
const { origin: { x, y } } = Placements.TOP.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.TOP.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(3);
expect(y).toEqual(0);
expect(y).toEqual(2);
});

it('* top start', () => {
const { origin: { x, y } } = Placements.TOP_START.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.TOP_START.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(2);
expect(y).toEqual(0);
expect(x).toEqual(4);
expect(y).toEqual(2);
});

it('* top end', () => {
const { origin: { x, y } } = Placements.TOP_END.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.TOP_END.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(4);
expect(y).toEqual(0);
expect(x).toEqual(2);
expect(y).toEqual(2);
});

it('* right', () => {
const { origin: { x, y } } = Placements.RIGHT.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.RIGHT.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(6);
expect(x).toEqual(4);
expect(y).toEqual(3);
});

it('* right start', () => {
const { origin: { x, y } } = Placements.RIGHT_START.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.RIGHT_START.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(6);
expect(y).toEqual(2);
expect(x).toEqual(4);
expect(y).toEqual(4);
});

it('* right end', () => {
const { origin: { x, y } } = Placements.RIGHT_END.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.RIGHT_END.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(6);
expect(y).toEqual(4);
expect(x).toEqual(4);
expect(y).toEqual(2);
});

it('* bottom', () => {
const { origin: { x, y } } = Placements.BOTTOM.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.BOTTOM.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(3);
expect(y).toEqual(6);
expect(y).toEqual(4);
});

it('* bottom start', () => {
const { origin: { x, y } } = Placements.BOTTOM_START.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.BOTTOM_START.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(2);
expect(y).toEqual(6);
expect(x).toEqual(4);
expect(y).toEqual(4);
});

it('* bottom end', () => {
const { origin: { x, y } } = Placements.BOTTOM_END.frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.BOTTOM_END.frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(4);
expect(y).toEqual(6);
expect(x).toEqual(2);
expect(y).toEqual(4);
});

});
Expand All @@ -152,87 +160,87 @@ describe('@type: popover model checks', () => {
const rhsFrame: Frame = new Frame(6, 6, 2, 2);

it('* left', () => {
const { origin: { x, y } } = Placements.LEFT.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.LEFT.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(6);
expect(x).toEqual(4);
expect(y).toEqual(3);
});

it('* left start', () => {
const { origin: { x, y } } = Placements.LEFT_START.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.LEFT_START.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(6);
expect(y).toEqual(2);
expect(x).toEqual(4);
expect(y).toEqual(4);
});

it('* left end', () => {
const { origin: { x, y } } = Placements.LEFT_END.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.LEFT_END.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(6);
expect(y).toEqual(4);
expect(x).toEqual(4);
expect(y).toEqual(2);
});

it('* top', () => {
const { origin: { x, y } } = Placements.TOP.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.TOP.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(3);
expect(y).toEqual(6);
expect(y).toEqual(4);
});

it('* top start', () => {
const { origin: { x, y } } = Placements.TOP_START.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.TOP_START.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(2);
expect(y).toEqual(6);
expect(x).toEqual(4);
expect(y).toEqual(4);
});

it('* top end', () => {
const { origin: { x, y } } = Placements.TOP_END.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.TOP_END.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(4);
expect(y).toEqual(6);
expect(x).toEqual(2);
expect(y).toEqual(4);
});

it('* right', () => {
const { origin: { x, y } } = Placements.RIGHT.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.RIGHT.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(0);
expect(x).toEqual(2);
expect(y).toEqual(3);
});

it('* right start', () => {
const { origin: { x, y } } = Placements.RIGHT_START.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.RIGHT_START.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(0);
expect(y).toEqual(2);
expect(x).toEqual(2);
expect(y).toEqual(4);
});

it('* right end', () => {
const { origin: { x, y } } = Placements.RIGHT_END.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.RIGHT_END.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(0);
expect(y).toEqual(4);
expect(x).toEqual(2);
expect(y).toEqual(2);
});

it('* bottom', () => {
const { origin: { x, y } } = Placements.BOTTOM.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.BOTTOM.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(3);
expect(y).toEqual(0);
expect(y).toEqual(2);
});

it('* bottom start', () => {
const { origin: { x, y } } = Placements.BOTTOM_START.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.BOTTOM_START.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(2);
expect(y).toEqual(0);
expect(x).toEqual(4);
expect(y).toEqual(2);
});

it('* bottom end', () => {
const { origin: { x, y } } = Placements.BOTTOM_END.reverse().frame(rhsFrame, lhsFrame);
const { origin: { x, y } } = Placements.BOTTOM_END.reverse().frame(rhsFrame, lhsFrame, marginOffsets);

expect(x).toEqual(4);
expect(y).toEqual(0);
expect(x).toEqual(2);
expect(y).toEqual(2);
});

});
Expand Down
Loading

0 comments on commit 1e3167b

Please sign in to comment.