Skip to content

Commit

Permalink
feat(cdk): manage edge cases (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
astagnol authored Jul 18, 2023
1 parent d249998 commit fa88aee
Show file tree
Hide file tree
Showing 23 changed files with 421 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const OcdkSurfaceBasicPositionList: string[] = [
'TOP_LEFT TOP_RIGHT',
'TOP_RIGHT TOP_LEFT',
'BOTTOM_LEFT BOTTOM_RIGHT',
'BOTTOM_RIGHT BOTTOM_LEFT',
'BOTTOM_LEFT TOP_LEFT',
'TOP_LEFT BOTTOM_LEFT',
'BOTTOM_RIGHT TOP_RIGHT',
'TOP_RIGHT BOTTOM_RIGHT',
'BOTTOM_CENTER TOP_CENTER',
'TOP_CENTER BOTTOM_CENTER',
];
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ocdk-surface-basic-position';
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ export class OcdkSurfaceTooltipExample {
case OcdkSurfaceTooltipPosition.RIGHT:
this.surface.setCornerPoints({ anchor: OcdkSurfaceCorner.TOP_RIGHT, origin: OcdkSurfaceCorner.TOP_LEFT });
break;
case OcdkSurfaceTooltipPosition.BOTTOM_CENTER:
this.surface.setCornerPoints({ anchor: OcdkSurfaceCorner.BOTTOM_CENTER, origin: OcdkSurfaceCorner.TOP_CENTER });
break;
case OcdkSurfaceTooltipPosition.TOP_CENTER:
this.surface.setCornerPoints({ anchor: OcdkSurfaceCorner.TOP_CENTER, origin: OcdkSurfaceCorner.BOTTOM_CENTER });
break;
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ export enum OcdkSurfaceTooltipPosition {
TOP = 'TOP',
BOTTOM = 'BOTTOM',
LEFT = 'LEFT',
RIGHT = 'RIGHT'
RIGHT = 'RIGHT',
BOTTOM_CENTER = 'BOTTOM_CENTER',
TOP_CENTER = 'TOP_CENTER',
}

export type OcdkSurfaceTooltipPositionUnion = `${OcdkSurfaceTooltipPosition}`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './ocdk-surface-basic-example/public-api';
export * from './ocdk-surface-tooltip-example/public-api';
export * from './ocdk-surface-select-example/public-api';
export * from './strategies/public-api';
9 changes: 9 additions & 0 deletions packages/libraries/cdk/dev/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,16 @@ <h3>tooltip example</h3>
<ocdk-surface-tooltip-example value="right positioning" position="right">
<button>tooltip at right</button>
</ocdk-surface-tooltip-example>
</div>

<h3>centered surface tooltip example</h3>
<div class="my-form-field">
<ocdk-surface-tooltip-example value="top_center positioning" position="top_center">
<button>tooltip at top center</button>
</ocdk-surface-tooltip-example>
<ocdk-surface-tooltip-example value="bottom_center positioning" position="bottom_center">
<button>tooltip at bottom center</button>
</ocdk-surface-tooltip-example>
</div>

</div>
Expand Down
1 change: 0 additions & 1 deletion packages/libraries/cdk/dev/src/www.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ logger.log('init');
}
}


(window as any).basic3Toggle = () => {
// synchronize the trigger element (anchor) with the surface when both are available
if (basicTrigger3 && basicSurface3) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ The main principles are:

## Symmetry position table

Positions that correspond to a `vertical` and `horizontal` positioning are defined (`green tick`).
Some are not available because of the overlapping of the `surface` container on top of the `anchor` (`red cross`).
Positions that correspond to a `vertical` and `horizontal` positioning are defined (`green tick`). The surface can be centered at the top or bottom of the trigger.
Some positions are not available because of the overlapping of the `surface` container on top of the `anchor` (`red cross`).

The `orange` arrows shows the position switching when there is not enough space on the vertical `Y` axis.
The `blue` arrows are here for horizontal axis.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ export enum OcdkSurfaceCorner {
TOP_LEFT = 0,
/** 4 */
TOP_RIGHT = OcdkSurfaceCornerBit.RIGHT,
/** 2 */
TOP_CENTER = OcdkSurfaceCornerBit.CENTER,
/** 1 */
BOTTOM_LEFT = OcdkSurfaceCornerBit.BOTTOM,
/** 5 */
BOTTOM_RIGHT = OcdkSurfaceCornerBit.BOTTOM | OcdkSurfaceCornerBit.RIGHT, // tslint:disable-line:no-bitwise
/** 3 */
BOTTOM_CENTER = 3,
/** 8 */
TOP_START = OcdkSurfaceCornerBit.FLIP_RTL,
/** 12 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ export enum OcdkSurfaceNormalizedCorner {
TOP_LEFT = 0,
/** 4 */
TOP_RIGHT = OcdkSurfaceCornerBit.RIGHT,
/** 2 */
TOP_CENTER = OcdkSurfaceCornerBit.CENTER,
/** 1 */
BOTTOM_LEFT = OcdkSurfaceCornerBit.BOTTOM,
/** 5 */
BOTTOM_RIGHT = OcdkSurfaceCornerBit.BOTTOM | OcdkSurfaceCornerBit.RIGHT, // tslint:disable-line:no-bitwise
/** 3 */
BOTTOM_CENTER = 3,
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { OcdkSurfaceStrategyDefiner } from '../../core/system/ocdk-surface-strategy-definer';
import { OcdkSurfaceStrategyDefinerConfig } from '../../core/system/ocdk-surface-strategy-definer-config';
import { OcdkSurfaceOnePositionStrategy } from '../../core/ocdk-surface-one-position-strategy';
import { ocdkSurfaceSymmetryBcTc } from './ocdk-surface-symmetry.bc-tc';
import { ocdkSurfaceSymmetryBlBr } from './ocdk-surface-symmetry.bl-br';
import { ocdkSurfaceSymmetryBlTl } from './ocdk-surface-symmetry.bl-tl';
import { ocdkSurfaceSymmetryBrBl } from './ocdk-surface-symmetry.br-bl';
Expand All @@ -9,6 +10,7 @@ import { ocdkSurfaceSymmetryTlBl } from './ocdk-surface-symmetry.tl-bl';
import { ocdkSurfaceSymmetryTrBr } from './ocdk-surface-symmetry.tr-br';
import { ocdkSurfaceSymmetryTlTr } from './ocdk-surface-symmetry.tl-tr';
import { ocdkSurfaceSymmetryTrTl } from './ocdk-surface-symmetry.tr-tl';
import { ocdkSurfaceSymmetryTcBc } from './ocdk-surface-symmetry.tc-bc';

/**
* global config to implement for the `symmetry` strategy
Expand All @@ -32,12 +34,14 @@ export class OcdkSurfaceSymmetryStrategy implements OcdkSurfaceStrategyDefiner<O
ocdkSurfaceSymmetryBrTr(), // BottomRight and TopRight
ocdkSurfaceSymmetryBrBl(), // BottomRight and BottomLeft
ocdkSurfaceSymmetryBlBr(), // BottomLeft and BottomRight
ocdkSurfaceSymmetryBcTc(), // BottomCenter and TopCenter

// ### anchored at top
ocdkSurfaceSymmetryTlBl(), // TopLeft and BottomLeft
ocdkSurfaceSymmetryTrBr(), // TopRight and BottomRight
ocdkSurfaceSymmetryTrTl(), // TopRight and TopLeft
ocdkSurfaceSymmetryTlTr() // TopLeft and TopRight
ocdkSurfaceSymmetryTlTr(), // TopLeft and TopRight
ocdkSurfaceSymmetryTcBc(), // TopCenter and BottomCenter
];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { OcdkSurfaceSymmetryConfig } from './ocdk-surface-symmetry-strategy';
import { OcdkSurfaceNormalizedCorner } from '../../core/ocdk-surface-normalized-corner';
import { OcdkLogger } from '../../../../logger/ocdk-logger';
import { OcdkSurfaceSymmetryStrategyHelpers } from './ocdk-surface-symmetry-strategy.helpers';
import {
isOcdkSurfaceStrategyComputeResultPosition
} from '../../core/system/ocdk-surface-strategy-compute-result-position';
import { OcdkSurfaceOnePositionStrategy } from '../../core/ocdk-surface-one-position-strategy';

/**
* ```
* x-----anchor-----+
* | |
* o----------------o
* o--surface--o
* | |
* +-----------+
*
* o = normalized corner
* x = reference for the position offset (at top/left - for verticalAlignment/horizontalAlignment)
* ```
*/
export function ocdkSurfaceSymmetryBcTc(): OcdkSurfaceOnePositionStrategy<OcdkSurfaceSymmetryConfig> {
const loggerSymmetry = new OcdkLogger('ocdkSurfaceSymmetryBcTc');
const helpers = OcdkSurfaceSymmetryStrategyHelpers;

return {
cornerPoints: { anchor: OcdkSurfaceNormalizedCorner.BOTTOM_CENTER, origin: OcdkSurfaceNormalizedCorner.TOP_CENTER },
STRATEGIES: {
standard: {
inspectors: {
comfort: {
availableTop: (opt) => opt.measurements.viewportDistance.top - opt.config.anchorMargin.top - opt.config.MARGIN_TO_EDGE_COMFORT + opt.measurements.anchorSize.height,
availableBottom: (opt) => opt.measurements.viewportDistance.bottom - opt.config.anchorMargin.bottom - opt.config.MARGIN_TO_EDGE_COMFORT,
availableLeft: (opt) => opt.measurements.viewportDistance.left - opt.config.anchorMargin.left - opt.config.MARGIN_TO_EDGE_COMFORT,
availableRight: (opt) => opt.measurements.viewportDistance.right - opt.config.anchorMargin.right - opt.config.MARGIN_TO_EDGE_COMFORT + opt.measurements.anchorSize.width
}
},
appliers: {
maxHeight: (opt) => opt.inspections.comfort.availableBottom,
maxWidth: (opt) => opt.measurements.surfaceSize.width,
verticalOffset: (opt) => opt.measurements.anchorSize.height + opt.config.anchorMargin.bottom,
verticalAlignment: 'top',
// center surface
horizontalOffset: (opt) => (opt.measurements.anchorSize.width - opt.measurements.surfaceSize.width)/2,
horizontalAlignment: 'right'
}
},
FALLBACK: {
inspectors: {
comfort: {
availableBottom: (opt) => opt.measurements.viewportSize.height - 2 * opt.config.MARGIN_TO_EDGE_COMFORT
},
limit: {
availableBottom: (opt) => opt.measurements.viewportSize.height - 2 * opt.config.MARGIN_TO_EDGE_LIMIT
},
},
appliers: {
maxHeight: (opt) => helpers.symmetryFallbackMaxHeight(opt, opt.inspections.comfort.availableBottom, opt.inspections.limit.availableBottom, true),
maxWidth: (opt) => opt.measurements.surfaceSize.width,
verticalOffset: (opt) => helpers.symmetryFallbackVerticalOffset(opt, opt.inspections.comfort.availableBottom, opt.inspections.limit.availableBottom, true),
verticalAlignment: 'top',
horizontalOffset: (opt) => (opt.measurements.anchorSize.width - opt.measurements.surfaceSize.width)/2,
horizontalAlignment: 'right'
}
},
COMPUTE: (opt) => {
loggerSymmetry.log('[COMPUTE] position BOTTOM_CENTER TOP_CENTER');
if (opt.measurements.surfaceSize.height > opt.inspections.comfort.availableBottom) {
// already in a switch process and this new position isn't good enough, go to the fallback of the last strategy position
if (opt.switchFrom && isOcdkSurfaceStrategyComputeResultPosition(opt.switchFrom) && opt.switchFrom.position) {
loggerSymmetry.log('[COMPUTE] already switched off but no enough space: continue with the fallback of bc-tc', opt.switchFrom);
return opt.switchFrom.position.STRATEGIES.FALLBACK;
}
// Check available space on right and left
switch (true) {
case opt.measurements.surfaceSize.width > opt.inspections.comfort.availableRight:
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_RIGHT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_RIGHT
}
};
case opt.measurements.surfaceSize.width > opt.inspections.comfort.availableLeft:
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_LEFT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_LEFT
}
};
default:
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_CENTER,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_CENTER
}
};
}
}
// Check available space on right and left
switch (true) {
case opt.measurements.surfaceSize.width > opt.inspections.comfort.availableRight:
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.BOTTOM_RIGHT,
origin: OcdkSurfaceNormalizedCorner.TOP_RIGHT
}
};
case opt.measurements.surfaceSize.width > opt.inspections.comfort.availableLeft:
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.BOTTOM_LEFT,
origin: OcdkSurfaceNormalizedCorner.TOP_LEFT
}
};
}
return; // no position switching: apply the current one
}

}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function ocdkSurfaceSymmetryBlBr(): OcdkSurfaceOnePositionStrategy<OcdkSu
}
},
appliers: {
maxHeight: (opt) => opt.inspections.comfort.availableBottom,
maxHeight: (opt) => opt.inspections.comfort.availableTop,
maxWidth: (opt) => opt.inspections.comfort.availableLeft,
verticalOffset: () => 0,
verticalAlignment: 'bottom',
Expand Down Expand Up @@ -72,12 +72,27 @@ export function ocdkSurfaceSymmetryBlBr(): OcdkSurfaceOnePositionStrategy<OcdkSu
loggerSymmetry.log('[COMPUTE] already switched off but no enough space: continue with the fallback of bl-br', opt.switchFrom);
return opt.switchFrom.position.STRATEGIES.FALLBACK;
}
if (opt.measurements.surfaceSize.height > opt.inspections.comfort.availableTop) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_RIGHT,
origin: OcdkSurfaceNormalizedCorner.TOP_LEFT
}
};
}
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.BOTTOM_RIGHT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_LEFT
}
};
} else if (opt.measurements.surfaceSize.height > opt.inspections.comfort.availableTop) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_LEFT,
origin: OcdkSurfaceNormalizedCorner.TOP_RIGHT
}
};
}
return; // no position switching: apply the current one
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,33 @@ export function ocdkSurfaceSymmetryBlTl(): OcdkSurfaceOnePositionStrategy<OcdkSu
},
COMPUTE: (opt) => {
loggerSymmetry.log('[COMPUTE] position BOTTOM_LEFT TOP_LEFT');
// no enough available space on bottom, trigger a position change to top instead
if (opt.measurements.surfaceSize.height > opt.inspections.comfort.availableBottom) {
// already in a switch process and this new position isn't good enough, go to the fallback of the last strategy position
if (opt.switchFrom && isOcdkSurfaceStrategyComputeResultPosition(opt.switchFrom) && opt.switchFrom.position) {
loggerSymmetry.log('[COMPUTE] already switched off but no enough space: continue with the fallback of bl-tl', opt.switchFrom);
return opt.switchFrom.position.STRATEGIES.FALLBACK;
}
if (opt.measurements.surfaceSize.width > opt.inspections.comfort.availableRight) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_RIGHT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_RIGHT
}
};
}
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_LEFT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_LEFT
}
};
} else if (opt.measurements.surfaceSize.width > opt.inspections.comfort.availableRight) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.BOTTOM_RIGHT,
origin: OcdkSurfaceNormalizedCorner.TOP_RIGHT
}
};
}
return; // no position switching: apply the current one
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function ocdkSurfaceSymmetryBrBl(): OcdkSurfaceOnePositionStrategy<OcdkSu
}
},
appliers: {
maxHeight: (opt) => opt.inspections.comfort.availableBottom,
maxHeight: (opt) => opt.inspections.comfort.availableTop,
maxWidth: (opt) => opt.inspections.comfort.availableRight,
verticalOffset: () => 0,
verticalAlignment: 'bottom',
Expand Down Expand Up @@ -71,12 +71,27 @@ export function ocdkSurfaceSymmetryBrBl(): OcdkSurfaceOnePositionStrategy<OcdkSu
loggerSymmetry.log('[COMPUTE] already switched off but no enough space: continue with the fallback of br-bl', opt.switchFrom);
return opt.switchFrom.position.STRATEGIES.FALLBACK;
}
if (opt.measurements.surfaceSize.height > opt.inspections.comfort.availableTop) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_LEFT,
origin: OcdkSurfaceNormalizedCorner.TOP_RIGHT
}
};
}
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.BOTTOM_LEFT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_RIGHT
}
};
} else if (opt.measurements.surfaceSize.height > opt.inspections.comfort.availableTop) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_RIGHT,
origin: OcdkSurfaceNormalizedCorner.TOP_LEFT
}
};
}
return; // no position switching: apply the current one
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,27 @@ export function ocdkSurfaceSymmetryBrTr(): OcdkSurfaceOnePositionStrategy<OcdkSu
loggerSymmetry.log('[COMPUTE] already switched off but no enough space: continue with the fallback of br-tr', opt.switchFrom);
return opt.switchFrom.position.STRATEGIES.FALLBACK;
}
if (opt.measurements.surfaceSize.width > opt.inspections.comfort.availableLeft) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_LEFT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_LEFT
}
};
}
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.TOP_RIGHT,
origin: OcdkSurfaceNormalizedCorner.BOTTOM_RIGHT
}
};
} else if (opt.measurements.surfaceSize.width > opt.inspections.comfort.availableLeft) {
return {
cornerPoints: {
anchor: OcdkSurfaceNormalizedCorner.BOTTOM_LEFT,
origin: OcdkSurfaceNormalizedCorner.TOP_LEFT
}
};
}
return; // no position switching: apply the current one
}
Expand Down
Loading

0 comments on commit fa88aee

Please sign in to comment.