amis-rpc-design/node_modules/antd/es/_util/placements.js
2023-10-07 19:42:30 +08:00

178 lines
4.5 KiB
JavaScript

import { getArrowOffset } from '../style/placementArrow';
export function getOverflowOptions(placement, arrowOffset, arrowWidth, autoAdjustOverflow) {
if (autoAdjustOverflow === false) {
return {
adjustX: false,
adjustY: false
};
}
const overflow = autoAdjustOverflow && typeof autoAdjustOverflow === 'object' ? autoAdjustOverflow : {};
const baseOverflow = {};
switch (placement) {
case 'top':
case 'bottom':
baseOverflow.shiftX = arrowOffset.dropdownArrowOffset * 2 + arrowWidth;
baseOverflow.shiftY = true;
baseOverflow.adjustY = true;
break;
case 'left':
case 'right':
baseOverflow.shiftY = arrowOffset.dropdownArrowOffsetVertical * 2 + arrowWidth;
baseOverflow.shiftX = true;
baseOverflow.adjustX = true;
break;
}
const mergedOverflow = Object.assign(Object.assign({}, baseOverflow), overflow);
// Support auto shift
if (!mergedOverflow.shiftX) {
mergedOverflow.adjustX = true;
}
if (!mergedOverflow.shiftY) {
mergedOverflow.adjustY = true;
}
return mergedOverflow;
}
const PlacementAlignMap = {
left: {
points: ['cr', 'cl']
},
right: {
points: ['cl', 'cr']
},
top: {
points: ['bc', 'tc']
},
bottom: {
points: ['tc', 'bc']
},
topLeft: {
points: ['bl', 'tl']
},
leftTop: {
points: ['tr', 'tl']
},
topRight: {
points: ['br', 'tr']
},
rightTop: {
points: ['tl', 'tr']
},
bottomRight: {
points: ['tr', 'br']
},
rightBottom: {
points: ['bl', 'br']
},
bottomLeft: {
points: ['tl', 'bl']
},
leftBottom: {
points: ['br', 'bl']
}
};
const ArrowCenterPlacementAlignMap = {
topLeft: {
points: ['bl', 'tc']
},
leftTop: {
points: ['tr', 'cl']
},
topRight: {
points: ['br', 'tc']
},
rightTop: {
points: ['tl', 'cr']
},
bottomRight: {
points: ['tr', 'bc']
},
rightBottom: {
points: ['bl', 'cr']
},
bottomLeft: {
points: ['tl', 'bc']
},
leftBottom: {
points: ['br', 'cl']
}
};
const DisableAutoArrowList = new Set(['topLeft', 'topRight', 'bottomLeft', 'bottomRight', 'leftTop', 'leftBottom', 'rightTop', 'rightBottom']);
export default function getPlacements(config) {
const {
arrowWidth,
autoAdjustOverflow,
arrowPointAtCenter,
offset,
borderRadius,
visibleFirst
} = config;
const halfArrowWidth = arrowWidth / 2;
const placementMap = {};
Object.keys(PlacementAlignMap).forEach(key => {
const template = arrowPointAtCenter && ArrowCenterPlacementAlignMap[key] || PlacementAlignMap[key];
const placementInfo = Object.assign(Object.assign({}, template), {
offset: [0, 0],
dynamicInset: true
});
placementMap[key] = placementInfo;
// Disable autoArrow since design is fixed position
if (DisableAutoArrowList.has(key)) {
placementInfo.autoArrow = false;
}
// Static offset
switch (key) {
case 'top':
case 'topLeft':
case 'topRight':
placementInfo.offset[1] = -halfArrowWidth - offset;
break;
case 'bottom':
case 'bottomLeft':
case 'bottomRight':
placementInfo.offset[1] = halfArrowWidth + offset;
break;
case 'left':
case 'leftTop':
case 'leftBottom':
placementInfo.offset[0] = -halfArrowWidth - offset;
break;
case 'right':
case 'rightTop':
case 'rightBottom':
placementInfo.offset[0] = halfArrowWidth + offset;
break;
}
// Dynamic offset
const arrowOffset = getArrowOffset({
contentRadius: borderRadius,
limitVerticalRadius: true
});
if (arrowPointAtCenter) {
switch (key) {
case 'topLeft':
case 'bottomLeft':
placementInfo.offset[0] = -arrowOffset.dropdownArrowOffset - halfArrowWidth;
break;
case 'topRight':
case 'bottomRight':
placementInfo.offset[0] = arrowOffset.dropdownArrowOffset + halfArrowWidth;
break;
case 'leftTop':
case 'rightTop':
placementInfo.offset[1] = -arrowOffset.dropdownArrowOffset - halfArrowWidth;
break;
case 'leftBottom':
case 'rightBottom':
placementInfo.offset[1] = arrowOffset.dropdownArrowOffset + halfArrowWidth;
break;
}
}
// Overflow
placementInfo.overflow = getOverflowOptions(key, arrowOffset, arrowWidth, autoAdjustOverflow);
// VisibleFirst
if (visibleFirst) {
placementInfo.htmlRegion = 'visibleFirst';
}
});
return placementMap;
}