@jobber/components-native 0.98.4 → 0.98.5

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.
Files changed (43) hide show
  1. package/dist/package.json +2 -2
  2. package/dist/src/index.js +0 -1
  3. package/dist/src/utils/meta/meta.json +0 -1
  4. package/dist/tsconfig.build.tsbuildinfo +1 -1
  5. package/dist/types/src/index.d.ts +0 -1
  6. package/package.json +2 -2
  7. package/src/index.ts +0 -1
  8. package/src/utils/meta/meta.json +0 -1
  9. package/dist/src/Menu/Menu.js +0 -85
  10. package/dist/src/Menu/Menu.style.js +0 -7
  11. package/dist/src/Menu/components/MenuOption/MenuOption.js +0 -27
  12. package/dist/src/Menu/components/MenuOption/MenuOption.style.js +0 -11
  13. package/dist/src/Menu/components/MenuOption/index.js +0 -1
  14. package/dist/src/Menu/components/Overlay/Overlay.js +0 -10
  15. package/dist/src/Menu/components/Overlay/Overlay.style.js +0 -8
  16. package/dist/src/Menu/components/Overlay/index.js +0 -1
  17. package/dist/src/Menu/index.js +0 -1
  18. package/dist/src/Menu/types.js +0 -1
  19. package/dist/src/Menu/utils.js +0 -78
  20. package/dist/types/src/Menu/Menu.d.ts +0 -3
  21. package/dist/types/src/Menu/Menu.style.d.ts +0 -18
  22. package/dist/types/src/Menu/components/MenuOption/MenuOption.d.ts +0 -3
  23. package/dist/types/src/Menu/components/MenuOption/MenuOption.style.d.ts +0 -8
  24. package/dist/types/src/Menu/components/MenuOption/index.d.ts +0 -1
  25. package/dist/types/src/Menu/components/Overlay/Overlay.d.ts +0 -3
  26. package/dist/types/src/Menu/components/Overlay/Overlay.style.d.ts +0 -12
  27. package/dist/types/src/Menu/components/Overlay/index.d.ts +0 -1
  28. package/dist/types/src/Menu/index.d.ts +0 -2
  29. package/dist/types/src/Menu/types.d.ts +0 -26
  30. package/dist/types/src/Menu/utils.d.ts +0 -11
  31. package/src/Menu/Menu.stories.tsx +0 -52
  32. package/src/Menu/Menu.style.ts +0 -17
  33. package/src/Menu/Menu.test.tsx +0 -203
  34. package/src/Menu/Menu.tsx +0 -141
  35. package/src/Menu/components/MenuOption/MenuOption.style.tsx +0 -12
  36. package/src/Menu/components/MenuOption/MenuOption.tsx +0 -66
  37. package/src/Menu/components/MenuOption/index.ts +0 -1
  38. package/src/Menu/components/Overlay/Overlay.style.ts +0 -15
  39. package/src/Menu/components/Overlay/Overlay.tsx +0 -18
  40. package/src/Menu/components/Overlay/index.ts +0 -1
  41. package/src/Menu/index.ts +0 -6
  42. package/src/Menu/types.ts +0 -31
  43. package/src/Menu/utils.ts +0 -148
@@ -1,203 +0,0 @@
1
- import React from "react";
2
- import { fireEvent, render } from "@testing-library/react-native";
3
- import { Host } from "react-native-portalize";
4
- import { View } from "react-native";
5
- import type { MenuOptionProps, MenuProps } from ".";
6
- import { Menu } from ".";
7
- import { tokens } from "../utils/design";
8
- import { Icon } from "../Icon";
9
- import { Button } from "../Button";
10
-
11
- const mockOnPress = jest.fn();
12
- jest
13
- .spyOn(View.prototype, "measureInWindow")
14
- .mockImplementation(cb => cb(50, 50, 100, 100));
15
-
16
- const setup = (props?: MenuProps) => {
17
- return render(
18
- <Host>
19
- <Menu
20
- menuOptions={props?.menuOptions}
21
- customActivator={props?.customActivator}
22
- />
23
- </Host>,
24
- );
25
- };
26
-
27
- const menuLabel = "Menu";
28
-
29
- describe("Menu", () => {
30
- beforeEach(() => {
31
- mockOnPress.mockClear();
32
- });
33
-
34
- it("renders the default Activator", () => {
35
- const { getByTestId, getByLabelText } = setup({
36
- menuOptions: [{ label: "hi", icon: "add", onPress: mockOnPress }],
37
- });
38
-
39
- expect(getByTestId("more")).toBeDefined();
40
- expect(getByLabelText(menuLabel)).toBeDefined();
41
- });
42
-
43
- it("renders every menu option when menu is opened", () => {
44
- const menuOptions: MenuOptionProps[] = [
45
- { label: "option1", icon: "add", onPress: mockOnPress },
46
- { label: "option2", icon: "arrowDown", onPress: mockOnPress },
47
- { label: "option3", onPress: mockOnPress },
48
- ];
49
- const { getByLabelText } = setup({
50
- menuOptions,
51
- });
52
-
53
- fireEvent.press(getByLabelText(menuLabel));
54
- expect(getByLabelText(menuOptions[0].label)).toBeDefined();
55
- expect(getByLabelText(menuOptions[1].label)).toBeDefined();
56
- expect(getByLabelText(menuOptions[2].label)).toBeDefined();
57
- });
58
-
59
- describe("Custom Activator", () => {
60
- it("renders a custom Activator", () => {
61
- const { getByTestId } = setup({
62
- menuOptions: [{ label: "hi", onPress: mockOnPress }],
63
- customActivator: <Icon name="addNote" />,
64
- });
65
-
66
- expect(getByTestId("addNote")).toBeDefined();
67
- });
68
-
69
- it("renders menu when the custom activator is clicked", () => {
70
- const { getByLabelText, getByTestId, getAllByTestId } = setup({
71
- menuOptions: [
72
- { label: "hi", icon: "add", onPress: mockOnPress },
73
- { label: "option2", onPress: mockOnPress },
74
- ],
75
- customActivator: <Icon name="addNote" />,
76
- });
77
-
78
- fireEvent.press(getByTestId("addNote"));
79
-
80
- expect(getAllByTestId("ATL-MENU-OPTIONS")).toHaveLength(2);
81
- expect(getByTestId("add")).toBeDefined();
82
- expect(getByLabelText("hi")).toBeDefined();
83
- });
84
-
85
- describe("Pressable used as Custom Activator", () => {
86
- it("menu is open and custom activator's onPress is called", () => {
87
- const mockActivatorPress = jest.fn();
88
- const buttonLabel = "Test me!";
89
- const menuOptions: MenuOptionProps[] = [
90
- { label: "menuOption", icon: "add", onPress: mockOnPress },
91
- ];
92
-
93
- const { getByLabelText } = setup({
94
- menuOptions,
95
- customActivator: (
96
- <Button label={buttonLabel} onPress={mockActivatorPress} />
97
- ),
98
- });
99
-
100
- fireEvent.press(getByLabelText(buttonLabel));
101
-
102
- expect(mockActivatorPress).toHaveBeenCalledTimes(1);
103
- expect(getByLabelText(menuOptions[0].label)).toBeDefined();
104
- });
105
- });
106
- });
107
-
108
- describe("Menu Options", () => {
109
- it("fires the onPress of the menu option", () => {
110
- const { getByLabelText } = setup({
111
- menuOptions: [
112
- {
113
- label: "hi",
114
- icon: "add",
115
- onPress: mockOnPress,
116
- destructive: true,
117
- },
118
- ],
119
- });
120
-
121
- fireEvent.press(getByLabelText(menuLabel));
122
- fireEvent.press(getByLabelText("hi"));
123
- expect(mockOnPress).toHaveBeenCalled();
124
- });
125
-
126
- it("renders a menuOption with an icon with destructive styling", () => {
127
- const { getByLabelText, getByTestId } = setup({
128
- menuOptions: [
129
- { label: "hi", icon: "add", onPress: mockOnPress, destructive: true },
130
- ],
131
- });
132
-
133
- fireEvent.press(getByLabelText(menuLabel));
134
- expect(getByTestId("add").props.style).toContainEqual({
135
- display: "flex",
136
- fill: tokens["color-critical"],
137
- height: 24,
138
- verticalAlign: "middle",
139
- width: 24,
140
- });
141
- });
142
-
143
- it("closes the menu after clicking on a menu option", () => {
144
- const { getByLabelText, queryByLabelText } = setup({
145
- menuOptions: [
146
- {
147
- label: "hi",
148
- icon: "add",
149
- onPress: mockOnPress,
150
- destructive: true,
151
- },
152
- ],
153
- });
154
-
155
- fireEvent.press(getByLabelText(menuLabel));
156
- fireEvent.press(getByLabelText("hi"));
157
- expect(mockOnPress).toHaveBeenCalled();
158
- expect(queryByLabelText("hi")).toBeNull();
159
- });
160
-
161
- it("transforms the text", () => {
162
- const { getByLabelText, getByText } = setup({
163
- menuOptions: [
164
- {
165
- label: "hi",
166
- icon: "add",
167
- onPress: mockOnPress,
168
- textTransform: "capitalize",
169
- },
170
- ],
171
- });
172
- fireEvent.press(getByLabelText(menuLabel));
173
- expect(getByText("Hi")).toBeDefined();
174
- });
175
-
176
- it("does not transform the text when textTransform set to none", () => {
177
- const { getByLabelText, getByText } = setup({
178
- menuOptions: [
179
- {
180
- label: "hi",
181
- icon: "add",
182
- onPress: mockOnPress,
183
- textTransform: "none",
184
- },
185
- ],
186
- });
187
- fireEvent.press(getByLabelText(menuLabel));
188
- expect(getByText("hi")).toBeDefined();
189
- });
190
- });
191
-
192
- it("renders a menu when the default activator is clicked", () => {
193
- const { getByLabelText, getByTestId } = setup({
194
- menuOptions: [{ label: "hi", icon: "add", onPress: mockOnPress }],
195
- });
196
-
197
- fireEvent.press(getByLabelText(menuLabel));
198
-
199
- expect(getByTestId("ATL-MENU-OPTIONS")).toBeDefined();
200
- expect(getByTestId("add")).toBeDefined();
201
- expect(getByLabelText("hi")).toBeDefined();
202
- });
203
- });
package/src/Menu/Menu.tsx DELETED
@@ -1,141 +0,0 @@
1
- import React, { useCallback, useRef, useState } from "react";
2
- import type { LayoutRectangle } from "react-native";
3
- import {
4
- Keyboard,
5
- Platform,
6
- Pressable,
7
- View,
8
- useWindowDimensions,
9
- } from "react-native";
10
- import { Portal } from "react-native-portalize";
11
- import { useSafeAreaFrame } from "react-native-safe-area-context";
12
- import { useStyles } from "./Menu.style";
13
- import { findViewpoint } from "./utils";
14
- import type { MenuProps } from "./types";
15
- import { MenuOption } from "./components/MenuOption";
16
- import { Overlay } from "./components/Overlay";
17
- import { Button } from "../Button";
18
- import { Content } from "../Content";
19
- import { useAtlantisContext } from "../AtlantisContext";
20
- import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
21
- import { useAtlantisTheme } from "../AtlantisThemeContext";
22
-
23
- export function Menu({ menuOptions, customActivator }: MenuProps) {
24
- const [open, setOpen] = useState<boolean>(false);
25
- const [menuPosition, setMenuPosition] = useState<object>();
26
- const activatorLayout = useRef<LayoutRectangle>(null);
27
- const menuButtonRef = useRef<View>(null);
28
- const screenInfo = useScreenInformation();
29
-
30
- const { t } = useAtlantisI18n();
31
- const styles = useStyles();
32
-
33
- const findMenuLayout = useCallback(() => {
34
- if (activatorLayout.current) {
35
- setMenuPosition(
36
- findViewpoint(screenInfo, activatorLayout.current, styles),
37
- );
38
- }
39
- }, [screenInfo, activatorLayout, styles]);
40
-
41
- const openMenu = () => {
42
- menuButtonRef.current?.measureInWindow(
43
- (x: number, y: number, width: number, height: number) => {
44
- activatorLayout.current = {
45
- x,
46
- y,
47
- width,
48
- height,
49
- };
50
- findMenuLayout();
51
- setOpen(true);
52
- },
53
- );
54
- };
55
-
56
- const activatorOnPress = (onPress?: () => void) => {
57
- onPress && onPress();
58
-
59
- if (Platform.OS === "ios" && Keyboard.isVisible()) {
60
- // On iOS, the keyboard height causes problems with the menu positioning logic.
61
- // Wait until the keyboard is fully hidden before we show the menu.
62
- onKeyboardDidHide(openMenu);
63
- Keyboard.dismiss();
64
- } else {
65
- openMenu();
66
- }
67
- };
68
-
69
- const { tokens } = useAtlantisTheme();
70
-
71
- return (
72
- <>
73
- <View
74
- ref={ref => {
75
- menuButtonRef.current = ref;
76
- }}
77
- collapsable={false}
78
- >
79
- {customActivator && (
80
- <Pressable
81
- style={({ pressed }) => [
82
- {
83
- opacity: pressed ? tokens["opacity-pressed"] : 1,
84
- },
85
- ]}
86
- pointerEvents="box-only"
87
- onPress={() => {
88
- activatorOnPress(customActivator.props.onPress);
89
- }}
90
- onLongPress={customActivator.props.onLongPress}
91
- >
92
- {customActivator}
93
- </Pressable>
94
- )}
95
-
96
- {!customActivator && (
97
- <Button
98
- icon="more"
99
- accessibilityLabel={t("menu")}
100
- variation="cancel"
101
- type="tertiary"
102
- onPress={() => {
103
- activatorOnPress();
104
- }}
105
- />
106
- )}
107
- </View>
108
- <Portal>
109
- {open && (
110
- <>
111
- <Overlay setOpen={setOpen} />
112
- <View style={[open && menuPosition, styles.menu]}>
113
- <Content spacing="none" childSpacing="small">
114
- {menuOptions?.map((menuOption, index) => {
115
- return (
116
- <MenuOption {...menuOption} key={index} setOpen={setOpen} />
117
- );
118
- })}
119
- </Content>
120
- </View>
121
- </>
122
- )}
123
- </Portal>
124
- </>
125
- );
126
- }
127
-
128
- function useScreenInformation() {
129
- const { headerHeight } = useAtlantisContext();
130
- const windowWidth = useWindowDimensions().width;
131
- const { height: windowHeight } = useSafeAreaFrame();
132
-
133
- return { headerHeight, windowWidth, windowHeight };
134
- }
135
-
136
- function onKeyboardDidHide(callback: () => void) {
137
- const listener = Keyboard.addListener("keyboardDidHide", () => {
138
- listener.remove();
139
- callback();
140
- });
141
- }
@@ -1,12 +0,0 @@
1
- import { buildThemedStyles } from "../../../AtlantisThemeContext";
2
-
3
- export const useStyles = buildThemedStyles(tokens => {
4
- return {
5
- menuOption: {
6
- display: "flex",
7
- paddingHorizontal: tokens["space-base"],
8
- paddingVertical: tokens["space-small"],
9
- borderRadius: tokens["radius-large"],
10
- },
11
- };
12
- });
@@ -1,66 +0,0 @@
1
- import React from "react";
2
- import { Pressable, View } from "react-native";
3
- import capitalize from "lodash/capitalize";
4
- import { useStyles } from "./MenuOption.style";
5
- import type { MenuOptionInternalProps } from "../../types";
6
- import { Flex } from "../../../Flex";
7
- import { Typography } from "../../../Typography";
8
- import { Icon } from "../../../Icon";
9
- import { useAtlantisTheme } from "../../../AtlantisThemeContext";
10
-
11
- export function MenuOption({
12
- label,
13
- icon,
14
- iconColor = "heading",
15
- textAlign,
16
- destructive,
17
- textTransform = "capitalize",
18
- onPress,
19
- setOpen,
20
- }: MenuOptionInternalProps) {
21
- const destructiveColor = "destructive";
22
- const textVariation = destructive ? destructiveColor : "heading";
23
- const styles = useStyles();
24
- const { tokens } = useAtlantisTheme();
25
-
26
- return (
27
- <View testID="ATL-MENU-OPTIONS">
28
- <Pressable
29
- style={({ pressed }) => [
30
- styles.menuOption,
31
- { opacity: pressed ? tokens["opacity-pressed"] : 1 },
32
- ]}
33
- onPress={() => {
34
- onPress();
35
- setOpen(false);
36
- }}
37
- accessibilityLabel={label}
38
- >
39
- <Flex
40
- template={["grow", "shrink"]}
41
- align={"flex-start"}
42
- gap={"smaller"}
43
- >
44
- <Typography
45
- selectable={false}
46
- color={textVariation}
47
- fontWeight={"semiBold"}
48
- lineHeight={"large"}
49
- align={textAlign}
50
- >
51
- {textTransform === "capitalize"
52
- ? capitalize(label.toLocaleLowerCase())
53
- : label}
54
- </Typography>
55
-
56
- {icon && (
57
- <Icon
58
- name={icon}
59
- color={destructive ? destructiveColor : iconColor}
60
- />
61
- )}
62
- </Flex>
63
- </Pressable>
64
- </View>
65
- );
66
- }
@@ -1 +0,0 @@
1
- export { MenuOption } from "./MenuOption";
@@ -1,15 +0,0 @@
1
- import { Dimensions, StyleSheet } from "react-native";
2
- import { buildThemedStyles } from "../../../AtlantisThemeContext";
3
-
4
- const { height } = Dimensions.get("window");
5
-
6
- export const useStyles = buildThemedStyles(tokens => {
7
- return {
8
- overlay: {
9
- ...StyleSheet.absoluteFillObject,
10
- backgroundColor: tokens["color-overlay"],
11
- opacity: 0,
12
- height,
13
- },
14
- };
15
- });
@@ -1,18 +0,0 @@
1
- import React from "react";
2
- import { Pressable, View } from "react-native";
3
- import { useStyles } from "./Overlay.style";
4
- import type { OverlayProp } from "../../types";
5
-
6
- export function Overlay({ setOpen }: OverlayProp) {
7
- const styles = useStyles();
8
-
9
- return (
10
- <Pressable
11
- onPressIn={() => {
12
- setOpen(false);
13
- }}
14
- >
15
- <View style={styles.overlay} />
16
- </Pressable>
17
- );
18
- }
@@ -1 +0,0 @@
1
- export { Overlay } from "./Overlay";
package/src/Menu/index.ts DELETED
@@ -1,6 +0,0 @@
1
- export { Menu } from "./Menu";
2
- export type {
3
- MenuProps,
4
- MenuOptionProps,
5
- MenuOptionInternalProps,
6
- } from "./types";
package/src/Menu/types.ts DELETED
@@ -1,31 +0,0 @@
1
- import type { ReactElement } from "react";
2
- import type { IconColorNames, IconNames } from "@jobber/design";
3
- import type { TextAlign } from "../Typography";
4
-
5
- export interface MenuOptionProps {
6
- readonly label: string;
7
- readonly icon?: IconNames;
8
- readonly iconColor?: IconColorNames;
9
- readonly textAlign?: TextAlign;
10
- readonly destructive?: boolean;
11
- readonly textTransform?: "none" | "capitalize";
12
- onPress: () => void;
13
- }
14
-
15
- export interface MenuOptionInternalProps extends MenuOptionProps {
16
- setOpen: (bool: boolean) => void;
17
- }
18
-
19
- export interface CustomActivatorProps {
20
- readonly onPress?: () => void;
21
- readonly onLongPress?: () => void;
22
- }
23
-
24
- export interface MenuProps {
25
- readonly menuOptions?: MenuOptionProps[];
26
- readonly customActivator?: ReactElement<CustomActivatorProps>;
27
- }
28
-
29
- export interface OverlayProp {
30
- setOpen: (bool: boolean) => void;
31
- }
package/src/Menu/utils.ts DELETED
@@ -1,148 +0,0 @@
1
- import type { LayoutRectangle } from "react-native";
2
- import type { useStyles } from "./Menu.style";
3
-
4
- interface ScreenInfo {
5
- windowHeight: number;
6
- headerHeight: number;
7
- windowWidth: number;
8
- }
9
-
10
- export function findViewpoint(
11
- screenInfo: ScreenInfo,
12
- activatorLayout: LayoutRectangle,
13
- styles: ReturnType<typeof useStyles>,
14
- ): { [key: string]: number | undefined } {
15
- const { windowHeight, windowWidth, headerHeight } = screenInfo;
16
- const pos: { [key: string]: number | undefined } = {};
17
- const menuWidth = styles.menu.width;
18
- const windowHalf = (windowHeight - headerHeight) / 2 + headerHeight;
19
- const menuPositionVertical =
20
- activatorLayout.y + activatorLayout.height > windowHalf
21
- ? "menuAbove"
22
- : "menuBelow";
23
-
24
- const menuPositionHorizontal =
25
- windowWidth / 2 > activatorLayout.width / 2 + activatorLayout.x
26
- ? "menuRight"
27
- : "menuLeft";
28
-
29
- const menuPadding = 36;
30
-
31
- getVerticalPosition(pos, windowHeight, activatorLayout, menuPositionVertical);
32
-
33
- getHorizontalPosition(
34
- pos,
35
- activatorLayout,
36
- windowWidth,
37
- menuPadding,
38
- menuWidth,
39
- menuPositionHorizontal,
40
- );
41
-
42
- return pos;
43
- }
44
-
45
- function getVerticalPosition(
46
- pos: { [key: string]: number | undefined },
47
- windowHeight: number,
48
- activatorLayout: LayoutRectangle,
49
- menuPositionVertical: string,
50
- ) {
51
- if (menuPositionVertical === "menuAbove") {
52
- getAbovePosition(pos, windowHeight, activatorLayout);
53
- }
54
-
55
- if (menuPositionVertical === "menuBelow") {
56
- getBelowPosition(pos, activatorLayout);
57
- }
58
- }
59
-
60
- function getBelowPosition(
61
- pos: { [key: string]: number | undefined },
62
- activatorLayout: LayoutRectangle,
63
- ) {
64
- pos.top = activatorLayout.y + activatorLayout.height;
65
- }
66
-
67
- function getAbovePosition(
68
- pos: { [key: string]: number | undefined },
69
- windowHeight: number,
70
- activatorLayout: LayoutRectangle,
71
- ) {
72
- pos.bottom = windowHeight - activatorLayout.y;
73
- }
74
-
75
- function getHorizontalPosition(
76
- pos: { [key: string]: number | undefined },
77
- activatorLayout: LayoutRectangle,
78
- windowWidth: number,
79
- menuPadding: number,
80
- menuWidth: number,
81
- menuPositionHorizontal: string,
82
- ) {
83
- if (menuPositionHorizontal === "menuRight") {
84
- getRightPosition(pos, activatorLayout, windowWidth, menuPadding, menuWidth);
85
- }
86
-
87
- if (menuPositionHorizontal === "menuLeft") {
88
- getLeftPosition(pos, activatorLayout, windowWidth, menuPadding, menuWidth);
89
- }
90
- }
91
-
92
- function getLeftPosition(
93
- pos: { [key: string]: number | undefined },
94
- activatorLayout: LayoutRectangle,
95
- windowWidth: number,
96
- menuHorizontalPadding: number,
97
- menuWidth: number,
98
- ) {
99
- const overflowLeft =
100
- windowWidth -
101
- activatorLayout.x -
102
- activatorLayout.width +
103
- activatorLayout.width / 2 -
104
- menuHorizontalPadding +
105
- menuWidth >
106
- windowWidth;
107
-
108
- const overflowRight =
109
- windowWidth -
110
- activatorLayout.x -
111
- activatorLayout.width +
112
- activatorLayout.width / 2 -
113
- menuHorizontalPadding <
114
- 0;
115
-
116
- if (overflowLeft) {
117
- pos.right = undefined;
118
- pos.left = 0;
119
- } else if (overflowRight) {
120
- pos.right = 0;
121
- } else {
122
- pos.right = windowWidth - activatorLayout.x - activatorLayout.width;
123
- }
124
- }
125
-
126
- function getRightPosition(
127
- pos: { [key: string]: number | undefined },
128
- activatorLayout: LayoutRectangle,
129
- windowWidth: number,
130
- menuPadding: number,
131
- menuWidth: number,
132
- ) {
133
- const overflowRight =
134
- activatorLayout.x + activatorLayout.width / 2 - menuPadding + menuWidth >
135
- windowWidth;
136
-
137
- const overflowLeft =
138
- activatorLayout.x + activatorLayout.width / 2 - menuPadding < 0;
139
-
140
- if (overflowRight) {
141
- pos.left = undefined;
142
- pos.right = 0;
143
- } else if (overflowLeft) {
144
- pos.left = 0;
145
- } else {
146
- pos.left = activatorLayout.x;
147
- }
148
- }