react-native-ui-lib 7.36.0 → 7.37.0-snapshot.6102
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/README.md +7 -0
- package/package.json +2 -2
- package/src/components/floatingButton/index.js +0 -1
- package/src/components/hint/Hint.driver.new.d.ts +19 -0
- package/src/components/hint/Hint.driver.new.js +19 -0
- package/src/components/hint/HintAnchor.d.ts +13 -0
- package/src/components/hint/HintAnchor.js +47 -0
- package/src/components/hint/HintBubble.d.ts +12 -0
- package/src/components/hint/HintBubble.js +64 -0
- package/src/components/hint/HintMockChildren.d.ts +8 -0
- package/src/components/hint/HintMockChildren.js +49 -0
- package/src/components/hint/HintOld.d.ts +196 -0
- package/src/components/hint/HintOld.js +549 -0
- package/src/components/hint/hooks/useHintAccessibility.d.ts +10 -0
- package/src/components/hint/hooks/useHintAccessibility.js +26 -0
- package/src/components/hint/hooks/useHintLayout.d.ts +13 -0
- package/src/components/hint/hooks/useHintLayout.js +66 -0
- package/src/components/hint/hooks/useHintPosition.d.ts +29 -0
- package/src/components/hint/hooks/useHintPosition.js +119 -0
- package/src/components/hint/hooks/useHintVisibility.d.ts +6 -0
- package/src/components/hint/hooks/useHintVisibility.js +26 -0
- package/src/components/hint/index.d.ts +17 -186
- package/src/components/hint/index.js +150 -403
- package/src/components/hint/types.d.ts +106 -0
- package/src/components/hint/types.js +11 -0
- package/src/components/picker/PickerItemsList.js +12 -3
- package/src/components/view/View.driver.new.js +2 -1
- package/src/incubator/expandableOverlay/index.d.ts +1 -0
- package/src/incubator/expandableOverlay/index.js +17 -5
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import _clamp from "lodash/clamp";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { Constants } from "../../../commons/new";
|
|
4
|
+
import { HintPositions, TargetAlignments } from "../types";
|
|
5
|
+
export default function useHintPosition({
|
|
6
|
+
isUsingModal,
|
|
7
|
+
targetLayoutState,
|
|
8
|
+
targetLayoutInWindowState,
|
|
9
|
+
position,
|
|
10
|
+
containerWidth,
|
|
11
|
+
useSideTip,
|
|
12
|
+
offset,
|
|
13
|
+
edgeMargins,
|
|
14
|
+
hintMessageWidth
|
|
15
|
+
}) {
|
|
16
|
+
const targetMidPosition = useMemo(() => {
|
|
17
|
+
if (targetLayoutInWindowState?.x !== undefined && targetLayoutInWindowState?.width) {
|
|
18
|
+
const midPosition = targetLayoutInWindowState?.x + targetLayoutInWindowState?.width / 2;
|
|
19
|
+
return Constants.isRTL ? containerWidth - midPosition : midPosition;
|
|
20
|
+
}
|
|
21
|
+
}, [targetLayoutInWindowState, containerWidth]);
|
|
22
|
+
const tipSize = useMemo(() => {
|
|
23
|
+
return useSideTip ? {
|
|
24
|
+
width: 14,
|
|
25
|
+
height: 7
|
|
26
|
+
} : {
|
|
27
|
+
width: 20,
|
|
28
|
+
height: 7
|
|
29
|
+
};
|
|
30
|
+
}, [useSideTip]);
|
|
31
|
+
|
|
32
|
+
// Calculate target's horizontal position on screen (left, center, right)
|
|
33
|
+
const targetAlignmentOnScreen = useMemo(() => {
|
|
34
|
+
const _containerWidth = containerWidth - edgeMargins * 2;
|
|
35
|
+
if (targetMidPosition !== undefined) {
|
|
36
|
+
if (targetMidPosition > _containerWidth * (4 / 5)) {
|
|
37
|
+
return TargetAlignments.RIGHT;
|
|
38
|
+
} else if (targetMidPosition < _containerWidth * (1 / 5)) {
|
|
39
|
+
return TargetAlignments.LEFT;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return TargetAlignments.CENTER;
|
|
43
|
+
}, [targetMidPosition, containerWidth, edgeMargins]);
|
|
44
|
+
|
|
45
|
+
// Calc the hint container - a full width rectangle that contains the hint bubble message
|
|
46
|
+
const hintContainerLayout = useMemo(() => {
|
|
47
|
+
const containerStyle = {
|
|
48
|
+
alignItems: 'flex-start'
|
|
49
|
+
};
|
|
50
|
+
if (targetLayoutInWindowState?.x !== undefined) {
|
|
51
|
+
containerStyle.left = -targetLayoutInWindowState.x;
|
|
52
|
+
}
|
|
53
|
+
if (position === HintPositions.TOP) {
|
|
54
|
+
containerStyle.bottom = 0;
|
|
55
|
+
} else if (targetLayoutInWindowState?.height) {
|
|
56
|
+
containerStyle.top = targetLayoutInWindowState.height;
|
|
57
|
+
}
|
|
58
|
+
return containerStyle;
|
|
59
|
+
}, [position, targetLayoutInWindowState]);
|
|
60
|
+
const hintPositionStyle = useMemo(() => {
|
|
61
|
+
const positionStyle = {
|
|
62
|
+
left: 0
|
|
63
|
+
};
|
|
64
|
+
if (targetMidPosition !== undefined && hintMessageWidth !== undefined) {
|
|
65
|
+
positionStyle.left = targetMidPosition;
|
|
66
|
+
positionStyle.left -= hintMessageWidth / 2;
|
|
67
|
+
positionStyle.left = _clamp(positionStyle.left, edgeMargins, containerWidth - edgeMargins - hintMessageWidth);
|
|
68
|
+
}
|
|
69
|
+
return positionStyle;
|
|
70
|
+
}, [hintMessageWidth, edgeMargins, containerWidth, targetMidPosition]);
|
|
71
|
+
const tipPositionStyle = useMemo(() => {
|
|
72
|
+
const positionStyle = {};
|
|
73
|
+
const _containerWidth = containerWidth - (isUsingModal ? 0 : edgeMargins);
|
|
74
|
+
if (position === HintPositions.TOP) {
|
|
75
|
+
positionStyle.bottom = offset - tipSize.height;
|
|
76
|
+
!useSideTip ? positionStyle.bottom += 1 : undefined;
|
|
77
|
+
} else {
|
|
78
|
+
positionStyle.top = offset - tipSize.height;
|
|
79
|
+
}
|
|
80
|
+
if (targetMidPosition !== undefined && targetLayoutInWindowState?.x !== undefined && targetLayoutInWindowState?.width && hintMessageWidth !== undefined) {
|
|
81
|
+
const layoutWidth = targetLayoutInWindowState?.width || 0;
|
|
82
|
+
const targetMidWidth = layoutWidth / 2;
|
|
83
|
+
const tipMidWidth = tipSize.width / 2;
|
|
84
|
+
let sideTipPosition = 0;
|
|
85
|
+
if (targetAlignmentOnScreen === TargetAlignments.LEFT || targetAlignmentOnScreen === TargetAlignments.CENTER) {
|
|
86
|
+
sideTipPosition = Math.max(hintPositionStyle.left, targetLayoutInWindowState.x);
|
|
87
|
+
} else if (targetAlignmentOnScreen === TargetAlignments.RIGHT) {
|
|
88
|
+
sideTipPosition = Math.min(hintPositionStyle.left + hintMessageWidth, targetLayoutInWindowState.x + targetLayoutInWindowState.width) - edgeMargins;
|
|
89
|
+
}
|
|
90
|
+
const leftPosition = useSideTip ? sideTipPosition : targetMidPosition - tipMidWidth;
|
|
91
|
+
const rightPosition = useSideTip ? _containerWidth - targetLayoutInWindowState.x - layoutWidth : _containerWidth - targetLayoutInWindowState.x - targetMidWidth - tipMidWidth;
|
|
92
|
+
positionStyle.left = Constants.isRTL ? rightPosition : leftPosition;
|
|
93
|
+
}
|
|
94
|
+
return positionStyle;
|
|
95
|
+
}, [targetMidPosition, targetLayoutInWindowState, hintMessageWidth, hintPositionStyle, containerWidth, position, targetAlignmentOnScreen, offset, useSideTip, tipSize, isUsingModal, edgeMargins]);
|
|
96
|
+
const hintPadding = useMemo(() => {
|
|
97
|
+
const paddings = {
|
|
98
|
+
paddingVertical: offset
|
|
99
|
+
};
|
|
100
|
+
return paddings;
|
|
101
|
+
}, [offset]);
|
|
102
|
+
|
|
103
|
+
// This is the offset between the target relative position and its absolute position on the screen
|
|
104
|
+
const targetScreenToRelativeOffset = useMemo(() => {
|
|
105
|
+
return {
|
|
106
|
+
left: (targetLayoutState?.x ?? 0) - (targetLayoutInWindowState?.x ?? 0),
|
|
107
|
+
top: (targetLayoutState?.y ?? 0) - (targetLayoutInWindowState?.y ?? 0)
|
|
108
|
+
};
|
|
109
|
+
}, [targetLayoutState, targetLayoutInWindowState]);
|
|
110
|
+
return {
|
|
111
|
+
tipSize,
|
|
112
|
+
targetAlignmentOnScreen,
|
|
113
|
+
hintContainerLayout,
|
|
114
|
+
tipPositionStyle,
|
|
115
|
+
hintPadding,
|
|
116
|
+
hintPositionStyle,
|
|
117
|
+
targetScreenToRelativeOffset
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useRef, useCallback, useState } from 'react';
|
|
2
|
+
import { Animated } from 'react-native';
|
|
3
|
+
import { useDidUpdate } from "../../../hooks";
|
|
4
|
+
const ANIMATION_DURATION = 170;
|
|
5
|
+
export default function useHintVisibility(visible) {
|
|
6
|
+
const [hintUnmounted, setHintUnmounted] = useState(!visible);
|
|
7
|
+
const visibleAnimated = useRef(new Animated.Value(Number(!!visible)));
|
|
8
|
+
useDidUpdate(() => {
|
|
9
|
+
animateHint();
|
|
10
|
+
}, [visible]);
|
|
11
|
+
const toggleAnimationEndedToRemoveHint = useCallback(() => {
|
|
12
|
+
setHintUnmounted(!visible);
|
|
13
|
+
}, [visible]);
|
|
14
|
+
const animateHint = useCallback(() => {
|
|
15
|
+
Animated.timing(visibleAnimated.current, {
|
|
16
|
+
toValue: Number(!!visible),
|
|
17
|
+
duration: ANIMATION_DURATION,
|
|
18
|
+
useNativeDriver: true
|
|
19
|
+
}).start(toggleAnimationEndedToRemoveHint);
|
|
20
|
+
}, [visible, toggleAnimationEndedToRemoveHint]);
|
|
21
|
+
return {
|
|
22
|
+
hintUnmounted,
|
|
23
|
+
visibilityProgress: visibleAnimated.current,
|
|
24
|
+
animateHint
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -1,191 +1,22 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
3
|
-
declare
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
declare enum HintPositions {
|
|
9
|
-
TOP = "top",
|
|
10
|
-
BOTTOM = "bottom"
|
|
11
|
-
}
|
|
12
|
-
interface HintTargetFrame {
|
|
13
|
-
x?: number;
|
|
14
|
-
y?: number;
|
|
15
|
-
width?: number;
|
|
16
|
-
height?: number;
|
|
17
|
-
}
|
|
18
|
-
type Position = Pick<ViewStyle, 'top' | 'bottom' | 'left' | 'right'>;
|
|
19
|
-
type HintPositionStyle = Position & Pick<ViewStyle, 'alignItems'>;
|
|
20
|
-
type Paddings = Pick<ViewStyle, 'paddingLeft' | 'paddingRight' | 'paddingVertical' | 'paddingHorizontal'>;
|
|
21
|
-
type ContentType = string | ReactElement;
|
|
22
|
-
export interface HintProps {
|
|
23
|
-
/**
|
|
24
|
-
* Control the visibility of the hint
|
|
25
|
-
*/
|
|
26
|
-
visible?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* The hint background color
|
|
29
|
-
*/
|
|
30
|
-
color?: string;
|
|
31
|
-
/**
|
|
32
|
-
* The hint message
|
|
33
|
-
*/
|
|
34
|
-
message?: ContentType | ContentType[];
|
|
35
|
-
/**
|
|
36
|
-
* The hint message custom style
|
|
37
|
-
*/
|
|
38
|
-
messageStyle?: StyleProp<TextStyle>;
|
|
39
|
-
/**
|
|
40
|
-
* Icon to show next to the hint's message
|
|
41
|
-
*/
|
|
42
|
-
icon?: ImageSourcePropType;
|
|
43
|
-
/**
|
|
44
|
-
* The icon's style
|
|
45
|
-
*/
|
|
46
|
-
iconStyle?: StyleProp<ImageStyle>;
|
|
47
|
-
/**
|
|
48
|
-
* The hint's position
|
|
49
|
-
*/
|
|
50
|
-
position?: HintPositions;
|
|
51
|
-
/**
|
|
52
|
-
* Provide custom target position instead of wrapping a child
|
|
53
|
-
*/
|
|
54
|
-
targetFrame?: HintTargetFrame;
|
|
55
|
-
/**
|
|
56
|
-
* Open the hint using a Modal component
|
|
57
|
-
*/
|
|
58
|
-
useModal?: boolean;
|
|
59
|
-
/**
|
|
60
|
-
* Show side tips instead of the middle tip
|
|
61
|
-
*/
|
|
62
|
-
useSideTip?: boolean;
|
|
63
|
-
/**
|
|
64
|
-
* The hint's border radius
|
|
65
|
-
*/
|
|
66
|
-
borderRadius?: number;
|
|
67
|
-
/**
|
|
68
|
-
* Hint margins from screen edges
|
|
69
|
-
*/
|
|
70
|
-
edgeMargins?: number;
|
|
71
|
-
/**
|
|
72
|
-
* Hint offset from target
|
|
73
|
-
*/
|
|
74
|
-
offset?: number;
|
|
75
|
-
/**
|
|
76
|
-
* Callback for Hint press
|
|
77
|
-
*/
|
|
78
|
-
onPress?: () => void;
|
|
79
|
-
/**
|
|
80
|
-
* Callback for the background press
|
|
81
|
-
*/
|
|
82
|
-
onBackgroundPress?: (event: GestureResponderEvent) => void;
|
|
83
|
-
/**
|
|
84
|
-
* Color for background overlay (require onBackgroundPress)
|
|
85
|
-
*/
|
|
86
|
-
backdropColor?: string;
|
|
87
|
-
/**
|
|
88
|
-
* The hint container width
|
|
89
|
-
*/
|
|
90
|
-
containerWidth?: number;
|
|
91
|
-
/**
|
|
92
|
-
* Custom content element to render inside the hint container
|
|
93
|
-
*/
|
|
94
|
-
customContent?: JSX.Element;
|
|
95
|
-
/**
|
|
96
|
-
* Remove all hint's paddings
|
|
97
|
-
*/
|
|
98
|
-
removePaddings?: boolean;
|
|
99
|
-
/**
|
|
100
|
-
* Enable shadow (for hint with white background only)
|
|
101
|
-
*/
|
|
102
|
-
enableShadow?: boolean;
|
|
103
|
-
/**
|
|
104
|
-
* The hint's test identifier
|
|
105
|
-
*/
|
|
106
|
-
testID?: string;
|
|
107
|
-
/**
|
|
108
|
-
* Additional styling
|
|
109
|
-
*/
|
|
110
|
-
style?: StyleProp<ViewStyle>;
|
|
111
|
-
children?: React.ReactNode;
|
|
112
|
-
}
|
|
113
|
-
interface HintState {
|
|
114
|
-
targetLayout?: HintTargetFrame;
|
|
115
|
-
targetLayoutInWindow?: HintTargetFrame;
|
|
116
|
-
hintUnmounted: boolean;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* @description: Hint component for displaying a tooltip over wrapped component
|
|
120
|
-
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/HintsScreen.tsx
|
|
121
|
-
* @notes: You can either wrap a component or pass a specific targetFrame
|
|
122
|
-
* @gif: https://github.com/wix/react-native-ui-lib/blob/master/demo/showcase/Hint/Hint.gif?raw=true
|
|
123
|
-
*/
|
|
124
|
-
declare class Hint extends Component<HintProps, HintState> {
|
|
125
|
-
static displayName: string;
|
|
126
|
-
static defaultProps: {
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HintPositions, HintProps } from './types';
|
|
3
|
+
declare const Hint: {
|
|
4
|
+
(props: HintProps): string | number | true | React.JSX.Element | Iterable<React.ReactNode> | null;
|
|
5
|
+
displayName: string;
|
|
6
|
+
defaultProps: {
|
|
127
7
|
position: HintPositions;
|
|
128
8
|
useModal: boolean;
|
|
129
9
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
height: number;
|
|
140
|
-
} | undefined;
|
|
141
|
-
targetLayout: HintTargetFrame | undefined;
|
|
142
|
-
hintUnmounted: boolean;
|
|
143
|
-
};
|
|
144
|
-
visibleAnimated: Animated.Value;
|
|
145
|
-
componentDidMount(): void;
|
|
146
|
-
componentDidUpdate(prevProps: HintProps): void;
|
|
147
|
-
animateHint: () => void;
|
|
148
|
-
toggleAnimationEndedToRemoveHint: () => void;
|
|
149
|
-
focusAccessibilityOnHint: () => void;
|
|
150
|
-
setTargetRef: (ref: ElementRef<typeof RNView>) => void;
|
|
151
|
-
onTargetLayout: ({ nativeEvent: { layout } }: LayoutChangeEvent) => void;
|
|
152
|
-
getAccessibilityInfo(): {
|
|
153
|
-
accessible: boolean;
|
|
154
|
-
accessibilityLabel: string;
|
|
155
|
-
} | undefined;
|
|
156
|
-
get containerWidth(): number;
|
|
157
|
-
get targetLayout(): HintTargetFrame | undefined;
|
|
158
|
-
get showHint(): boolean;
|
|
159
|
-
get tipSize(): {
|
|
160
|
-
width: number;
|
|
161
|
-
height: number;
|
|
162
|
-
};
|
|
163
|
-
get hintOffset(): number;
|
|
164
|
-
get edgeMargins(): number;
|
|
165
|
-
get useSideTip(): boolean;
|
|
166
|
-
getTargetPositionOnScreen(): TARGET_POSITIONS;
|
|
167
|
-
getContainerPosition(): {
|
|
168
|
-
top: number | undefined;
|
|
169
|
-
left: number | undefined;
|
|
170
|
-
} | undefined;
|
|
171
|
-
getHintPosition(): HintPositionStyle;
|
|
172
|
-
getHintPadding(): Paddings;
|
|
173
|
-
getHintAnimatedStyle: () => {
|
|
174
|
-
opacity: Animated.Value;
|
|
175
|
-
transform: {
|
|
176
|
-
translateY: Animated.AnimatedInterpolation<string | number>;
|
|
177
|
-
}[];
|
|
10
|
+
positions: typeof HintPositions;
|
|
11
|
+
};
|
|
12
|
+
export { HintProps, Hint };
|
|
13
|
+
declare const _default: React.ForwardRefExoticComponent<HintProps & React.RefAttributes<any>> & {
|
|
14
|
+
(props: HintProps): string | number | true | React.JSX.Element | Iterable<React.ReactNode> | null;
|
|
15
|
+
displayName: string;
|
|
16
|
+
defaultProps: {
|
|
17
|
+
position: HintPositions;
|
|
18
|
+
useModal: boolean;
|
|
178
19
|
};
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
renderOverlay(): React.JSX.Element | undefined;
|
|
182
|
-
renderHintTip(): React.JSX.Element;
|
|
183
|
-
renderContent(): React.JSX.Element;
|
|
184
|
-
renderHint(): React.JSX.Element | undefined;
|
|
185
|
-
renderHintContainer(): React.JSX.Element;
|
|
186
|
-
renderMockChildren(): React.JSX.Element | undefined;
|
|
187
|
-
renderChildren(): React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
|
|
188
|
-
render(): string | number | true | React.JSX.Element | Iterable<React.ReactNode> | null;
|
|
189
|
-
}
|
|
190
|
-
declare const _default: React.ForwardRefExoticComponent<HintProps & React.RefAttributes<any>> & typeof Hint;
|
|
20
|
+
positions: typeof HintPositions;
|
|
21
|
+
};
|
|
191
22
|
export default _default;
|