@vention/machine-ui 3.35.0 → 3.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js
CHANGED
|
@@ -11996,4 +11996,111 @@ const useStyle = tss$1.withParams().create(({
|
|
|
11996
11996
|
};
|
|
11997
11997
|
});
|
|
11998
11998
|
|
|
11999
|
-
|
|
11999
|
+
const POSITIONED_MENU_OFFSET = 3;
|
|
12000
|
+
/**
|
|
12001
|
+
* Generic positioned component that can position any React component based on viewport constraints.
|
|
12002
|
+
* It can be positioned relative to an anchor element or a specified position.
|
|
12003
|
+
*
|
|
12004
|
+
* @param props - The properties for the positioned component, including position and children.
|
|
12005
|
+
* @returns The positioned component wrapper.
|
|
12006
|
+
*/
|
|
12007
|
+
function VentionPositionedComponent({
|
|
12008
|
+
position,
|
|
12009
|
+
anchorRect,
|
|
12010
|
+
placement = "bottom",
|
|
12011
|
+
alignment = "start",
|
|
12012
|
+
children
|
|
12013
|
+
}) {
|
|
12014
|
+
const ref = useRef(null);
|
|
12015
|
+
const [adjustedPosition, setAdjustedPosition] = useState({
|
|
12016
|
+
top: 0,
|
|
12017
|
+
left: 0
|
|
12018
|
+
});
|
|
12019
|
+
useEffect(() => {
|
|
12020
|
+
const {
|
|
12021
|
+
width,
|
|
12022
|
+
height
|
|
12023
|
+
} = ref.current.getBoundingClientRect();
|
|
12024
|
+
let top = 0;
|
|
12025
|
+
let left = 0;
|
|
12026
|
+
if (position !== undefined) {
|
|
12027
|
+
top = position.top;
|
|
12028
|
+
left = position.left;
|
|
12029
|
+
} else {
|
|
12030
|
+
const calculatedPosition = calcMenuPosition(anchorRect, {
|
|
12031
|
+
width,
|
|
12032
|
+
height
|
|
12033
|
+
}, placement, alignment);
|
|
12034
|
+
top = calculatedPosition.top;
|
|
12035
|
+
left = calculatedPosition.left;
|
|
12036
|
+
}
|
|
12037
|
+
// Clamp to viewport
|
|
12038
|
+
const maxLeft = Math.max(0, window.innerWidth - width);
|
|
12039
|
+
const maxTop = Math.max(0, window.innerHeight - height);
|
|
12040
|
+
left = Math.min(Math.max(left, 0), maxLeft);
|
|
12041
|
+
top = Math.min(Math.max(top, 0), maxTop);
|
|
12042
|
+
setAdjustedPosition({
|
|
12043
|
+
top,
|
|
12044
|
+
left
|
|
12045
|
+
});
|
|
12046
|
+
}, [position, anchorRect, placement, alignment, children]);
|
|
12047
|
+
return jsx("div", {
|
|
12048
|
+
ref: ref,
|
|
12049
|
+
style: {
|
|
12050
|
+
position: "fixed",
|
|
12051
|
+
top: adjustedPosition.top,
|
|
12052
|
+
left: adjustedPosition.left,
|
|
12053
|
+
zIndex: machineUiTheme.zIndex.modal
|
|
12054
|
+
},
|
|
12055
|
+
children: children
|
|
12056
|
+
});
|
|
12057
|
+
}
|
|
12058
|
+
function calcMenuPosition(anchorRect, menuSize, placement, alignment) {
|
|
12059
|
+
const {
|
|
12060
|
+
width,
|
|
12061
|
+
height
|
|
12062
|
+
} = menuSize;
|
|
12063
|
+
const {
|
|
12064
|
+
left,
|
|
12065
|
+
top,
|
|
12066
|
+
right,
|
|
12067
|
+
bottom,
|
|
12068
|
+
width: anchorWidth,
|
|
12069
|
+
height: anchorHeight
|
|
12070
|
+
} = anchorRect;
|
|
12071
|
+
const offset = POSITIONED_MENU_OFFSET;
|
|
12072
|
+
const align = (alignment, start, end, anchorSize, size) => {
|
|
12073
|
+
switch (alignment) {
|
|
12074
|
+
case "start":
|
|
12075
|
+
return start;
|
|
12076
|
+
case "end":
|
|
12077
|
+
return end - size;
|
|
12078
|
+
case "middle":
|
|
12079
|
+
return start + (anchorSize - size) / 2;
|
|
12080
|
+
}
|
|
12081
|
+
};
|
|
12082
|
+
switch (placement) {
|
|
12083
|
+
case "bottom":
|
|
12084
|
+
return {
|
|
12085
|
+
top: bottom + offset,
|
|
12086
|
+
left: align(alignment, left, right, anchorWidth, width)
|
|
12087
|
+
};
|
|
12088
|
+
case "top":
|
|
12089
|
+
return {
|
|
12090
|
+
top: top - height - offset,
|
|
12091
|
+
left: align(alignment, left, right, anchorWidth, width)
|
|
12092
|
+
};
|
|
12093
|
+
case "right":
|
|
12094
|
+
return {
|
|
12095
|
+
left: right + offset,
|
|
12096
|
+
top: align(alignment, top, bottom, anchorHeight, height)
|
|
12097
|
+
};
|
|
12098
|
+
default:
|
|
12099
|
+
return {
|
|
12100
|
+
left: left - width - offset,
|
|
12101
|
+
top: align(alignment, top, bottom, anchorHeight, height)
|
|
12102
|
+
};
|
|
12103
|
+
}
|
|
12104
|
+
}
|
|
12105
|
+
|
|
12106
|
+
export { COLORS, DEFAULT_VENTION_TREE_ITEM_HEIGHT, ElementTestIds, IconSizes, POSITIONED_MENU_OFFSET, VentionAlert, VentionBadge, VentionBanner, VentionButton, VentionCallout, VentionCheckbox, VentionCombobox, VentionCounter, VentionDraggable, VentionDrawer, VentionDropZone, VentionDropdownButton, VentionIcon, VentionIconButton, VentionLink, VentionMenu, VentionModal, VentionModalBanner, VentionModalBase, VentionPopover, VentionPositionedComponent, VentionProgressBar, VentionRadio, VentionRadioTile, VentionSelect, VentionSidebarItem, VentionSlider, VentionSpinner, VentionStatusDot, VentionStatusIndicator, VentionStepper, VentionSteps, VentionSwitch, VentionTabs, VentionTextInput, VentionTooltip, VentionTreeItem, VentionUploadFile, calcMenuPosition, getSpinnerColor, getVentionBadgeColors, machineUiHmiTheme, machineUiTheme, testIds, useBannerColorStyles, ventionModalBaseTestIds, ventionModalTestIds, ventionPopoverArrowSize };
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ export * from "./lib/components/vention-tooltip/vention-tooltip";
|
|
|
36
36
|
export * from "./lib/components/vention-checkbox/vention-checkbox";
|
|
37
37
|
export * from "./lib/components/vention-uploadfile/vention-uploadfile";
|
|
38
38
|
export * from "./lib/components/vention-dropzone/vention-dropzone";
|
|
39
|
+
export * from "./lib/components/shared/vention-positioned-component";
|
|
39
40
|
export * from "./lib/theme/machine-ui-theme";
|
|
40
41
|
export * from "./lib/theme/colors";
|
|
41
42
|
export { type VentionAlertProps } from "./lib/components/vention-alert/vention-alert-utils";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type AnchorPosition = {
|
|
3
|
+
top: number;
|
|
4
|
+
left: number;
|
|
5
|
+
};
|
|
6
|
+
export type PositionedMenuPlacement = "bottom" | "top" | "left" | "right";
|
|
7
|
+
export type PositionedMenuAlignment = "start" | "middle" | "end";
|
|
8
|
+
export declare const POSITIONED_MENU_OFFSET = 3;
|
|
9
|
+
interface BasePositionedProps {
|
|
10
|
+
placement?: PositionedMenuPlacement | undefined;
|
|
11
|
+
alignment?: PositionedMenuAlignment | undefined;
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
interface PositionedPropsWithAnchor extends BasePositionedProps {
|
|
15
|
+
anchorRect: DOMRect;
|
|
16
|
+
position?: never;
|
|
17
|
+
}
|
|
18
|
+
interface PositionedPropsWithPosition extends BasePositionedProps {
|
|
19
|
+
anchorRect?: never;
|
|
20
|
+
position: AnchorPosition;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Props for the positioned component.
|
|
24
|
+
* Either position or anchorRect must be defined, but not both.
|
|
25
|
+
*/
|
|
26
|
+
export type PositionedComponentProps = PositionedPropsWithAnchor | PositionedPropsWithPosition;
|
|
27
|
+
/**
|
|
28
|
+
* Generic positioned component that can position any React component based on viewport constraints.
|
|
29
|
+
* It can be positioned relative to an anchor element or a specified position.
|
|
30
|
+
*
|
|
31
|
+
* @param props - The properties for the positioned component, including position and children.
|
|
32
|
+
* @returns The positioned component wrapper.
|
|
33
|
+
*/
|
|
34
|
+
export declare function VentionPositionedComponent({ position, anchorRect, placement, alignment, children, }: PositionedComponentProps): JSX.Element;
|
|
35
|
+
export declare function calcMenuPosition(anchorRect: DOMRect, menuSize: {
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
}, placement: PositionedMenuPlacement, alignment: PositionedMenuAlignment): AnchorPosition;
|
|
39
|
+
export {};
|