-
Notifications
You must be signed in to change notification settings - Fork 734
Hint Refactor #3486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hint Refactor #3486
Changes from all commits
930a844
084f150
26ef738
3414fff
019f317
a08f6f5
f651253
5afbf8f
c2c3d9b
80ed235
40b18be
139b8ac
06006e0
3228021
26ceaac
1543cea
cde322d
4b38f7b
598312d
5d230ce
56bc7d9
4ea0f45
a9811ce
c6e1eca
0b12ec8
f5016b2
437ced7
e0fb900
f36d7c7
ce2d872
e231f4b
86bc627
afc0866
563f758
f3b447c
c0c1700
5c6dac0
95f9e5a
094a94b
fa45014
e4c594d
bdd2ff7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ type HintScreenProps = {}; | |
export default class HintsScreen extends Component<HintScreenProps> { | ||
state = { | ||
showHint: true, | ||
showSecondHint: false, | ||
useShortMessage: false, | ||
showBottomHint: false, | ||
showIcon: false, | ||
|
@@ -28,6 +29,10 @@ export default class HintsScreen extends Component<HintScreenProps> { | |
this.setState({showHint: !this.state.showHint}); | ||
}; | ||
|
||
toggleSecondHint = () => { | ||
this.setState({showSecondHint: !this.state.showSecondHint}); | ||
}; | ||
|
||
toggleHintPosition = () => { | ||
this.setState({ | ||
showBottomHint: !this.state.showBottomHint | ||
|
@@ -92,7 +97,7 @@ export default class HintsScreen extends Component<HintScreenProps> { | |
|
||
{renderMultipleSegmentOptions.call(this, 'Tip Position', 'useSideTip', [ | ||
{label: 'Side Tip', value: true}, | ||
{label: 'Middle Top', value: false} | ||
{label: 'Middle Tip', value: false} | ||
])} | ||
|
||
{renderMultipleSegmentOptions.call(this, 'Hint Position', 'showBottomHint', [ | ||
|
@@ -118,6 +123,7 @@ export default class HintsScreen extends Component<HintScreenProps> { | |
render() { | ||
const { | ||
showHint, | ||
showSecondHint, | ||
showBottomHint, | ||
showIcon, | ||
targetPosition, | ||
|
@@ -135,6 +141,8 @@ export default class HintsScreen extends Component<HintScreenProps> { | |
: 'Add other cool and useful stuff through adding apps to your visitors to enjoy.'; | ||
const color = !showCustomContent && showReactionStrip ? {color: Colors.$backgroundDefault} : undefined; | ||
|
||
const hintKey = `${useSideTip}-${targetPosition}-${useShortMessage}-${showIcon}-${useTargetFrame}-${showCustomContent}-${showReactionStrip}`; | ||
|
||
return ( | ||
<View flex> | ||
<View | ||
|
@@ -164,7 +172,7 @@ export default class HintsScreen extends Component<HintScreenProps> { | |
// offset={35} | ||
position={showBottomHint ? Hint.positions.BOTTOM : Hint.positions.TOP} | ||
useSideTip={useSideTip} | ||
key={targetPosition} | ||
key={hintKey} | ||
onPress={this.onHintPressed} | ||
targetFrame={useTargetFrame ? targetFrame : undefined} | ||
// borderRadius={BorderRadiuses.br40} | ||
|
@@ -215,6 +223,19 @@ export default class HintsScreen extends Component<HintScreenProps> { | |
</View> | ||
</> | ||
)} | ||
|
||
<View marginT-100 row center> | ||
{targetPosition !== 'flex-start' && <Text marginH-s3>Text pushing button</Text>} | ||
<Hint | ||
message={'Hint'} | ||
visible={showSecondHint} | ||
onBackgroundPress={this.toggleSecondHint} | ||
useSideTip={false} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useSideTip must be false or we can play with this from the switches? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Passing true will result in a wrong UI that looks bad, it's not a bug, it's just not meant for that so I rather pass false |
||
> | ||
<Button label="Button" onPress={this.toggleSecondHint}/> | ||
</Hint> | ||
{targetPosition === 'flex-start' && <Text marginH-s3>Text pushing button</Text>} | ||
</View> | ||
</View> | ||
|
||
{this.renderOptionsFAB()} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver'; | ||
import {ModalDriver} from '../modal/Modal.driver.new'; | ||
import {ViewDriver} from '../view/View.driver.new'; | ||
|
||
export const HintDriver = (props: ComponentProps) => { | ||
const driver = useComponentDriver(props); | ||
|
||
const hintBubbleDriver = ViewDriver({ | ||
renderTree: props.renderTree, | ||
testID: `${props.testID}.message` | ||
}); | ||
|
||
const modalDriver = ModalDriver({renderTree: props.renderTree, testID: `${props.testID}.message`}); | ||
|
||
return { | ||
...driver, | ||
getHintBubble: () => hintBubbleDriver, | ||
getModal: () => modalDriver | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React from 'react'; | ||
import {StyleSheet, type LayoutRectangle} from 'react-native'; | ||
|
||
import View from '../view'; | ||
|
||
import {LayoutStyle, HintProps, PaddingsStyle} from './types'; | ||
|
||
interface HintAnchorProps extends HintProps { | ||
showHint: boolean; | ||
isUsingModal: boolean; | ||
targetLayout?: LayoutRectangle; | ||
hintContainerLayout: LayoutStyle; | ||
hintPadding: PaddingsStyle; | ||
hintAnimatedStyle: any; | ||
} | ||
|
||
export default function HintAnchor({ | ||
children, | ||
showHint, | ||
isUsingModal, | ||
targetLayout, | ||
containerWidth, | ||
testID, | ||
hintContainerLayout, | ||
hintPadding, | ||
hintAnimatedStyle, | ||
style, | ||
...others | ||
}: HintAnchorProps) { | ||
const renderHintContainer = () => { | ||
if (showHint) { | ||
return ( | ||
<View | ||
animated | ||
style={[ | ||
{width: containerWidth}, | ||
styles.animatedContainer, | ||
hintContainerLayout, | ||
hintPadding, | ||
hintAnimatedStyle | ||
]} | ||
pointerEvents="box-none" | ||
testID={testID} | ||
> | ||
{children} | ||
</View> | ||
); | ||
} | ||
}; | ||
|
||
return ( | ||
<View | ||
{...others} | ||
// Note: this view must be collapsable, don't pass testID or backgroundColor etc'. | ||
collapsable | ||
testID={undefined} | ||
style={[ | ||
styles.anchor, | ||
style, | ||
/* containerPosition, */ | ||
{left: targetLayout?.x, top: targetLayout?.y}, | ||
!isUsingModal && styles.anchorForScreenOverlay | ||
]} | ||
> | ||
{renderHintContainer()} | ||
</View> | ||
); | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
anchor: { | ||
position: 'absolute' | ||
}, | ||
anchorForScreenOverlay: { | ||
zIndex: 10, | ||
elevation: 10 | ||
}, | ||
animatedContainer: { | ||
position: 'absolute' | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import React from 'react'; | ||
import {StyleSheet, View as RNView, LayoutChangeEvent} from 'react-native'; | ||
import _ from 'lodash'; | ||
|
||
import {Constants} from '../../commons/new'; | ||
import {BorderRadiuses, Colors, Shadows, Spacings, Typography} from 'style'; | ||
import View from '../view'; | ||
import Text from '../text'; | ||
import Image from '../image'; | ||
import {HintProps} from './types'; | ||
|
||
const DEFAULT_COLOR = Colors.$backgroundPrimaryHeavy; | ||
// const HINT_MIN_WIDTH = 68; | ||
|
||
interface HintBubbleProps | ||
extends Pick< | ||
HintProps, | ||
| 'testID' | ||
| 'visible' | ||
| 'message' | ||
| 'messageStyle' | ||
| 'color' | ||
| 'removePaddings' | ||
| 'enableShadow' | ||
| 'borderRadius' | ||
| 'iconStyle' | ||
| 'icon' | ||
| 'customContent' | ||
> { | ||
hintRef: React.RefObject<RNView>; | ||
setHintLayout: (layoutChangeEvent: LayoutChangeEvent) => void; | ||
hintPositionStyle: {left: number}; | ||
} | ||
|
||
export default function HintBubble({ | ||
visible, | ||
message, | ||
messageStyle, | ||
icon, | ||
iconStyle, | ||
borderRadius, | ||
removePaddings, | ||
enableShadow, | ||
color, | ||
customContent, | ||
testID, | ||
hintRef, | ||
hintPositionStyle, | ||
setHintLayout | ||
}: HintBubbleProps) { | ||
return ( | ||
<View | ||
testID={`${testID}.message`} | ||
row | ||
centerV | ||
style={[ | ||
styles.hint, | ||
!removePaddings && styles.hintPaddings, | ||
visible && enableShadow && styles.containerShadow, | ||
{backgroundColor: color}, | ||
!_.isUndefined(borderRadius) && {borderRadius}, | ||
hintPositionStyle | ||
]} | ||
onLayout={setHintLayout} | ||
ref={hintRef} | ||
> | ||
{customContent} | ||
{!customContent && icon && <Image source={icon} style={[styles.icon, iconStyle]}/>} | ||
{!customContent && ( | ||
<Text recorderTag={'unmask'} style={[styles.hintMessage, messageStyle]} testID={`${testID}.message.text`}> | ||
{message} | ||
</Text> | ||
)} | ||
</View> | ||
); | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
hint: { | ||
// minWidth: HINT_MIN_WIDTH, | ||
maxWidth: Math.min(Constants.windowWidth - 2 * Spacings.s4, 400), | ||
borderRadius: BorderRadiuses.br60, | ||
backgroundColor: DEFAULT_COLOR | ||
}, | ||
hintPaddings: { | ||
paddingHorizontal: Spacings.s5, | ||
paddingTop: Spacings.s3, | ||
paddingBottom: Spacings.s4 | ||
}, | ||
containerShadow: { | ||
...Shadows.sh30.bottom | ||
}, | ||
hintMessage: { | ||
...Typography.text70, | ||
color: Colors.white, | ||
flexShrink: 1 | ||
}, | ||
icon: { | ||
marginRight: Spacings.s4, | ||
tintColor: Colors.white | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React from 'react'; | ||
import {StyleSheet, LayoutRectangle} from 'react-native'; | ||
|
||
import {Constants} from '../../commons/new'; | ||
import View from '../view'; | ||
import {HintProps} from './types'; | ||
|
||
interface HintMockChildrenProps extends Pick<HintProps, 'children' | 'backdropColor'> { | ||
targetLayout?: LayoutRectangle; | ||
} | ||
|
||
export default function HintMockChildren({children, backdropColor, targetLayout}: HintMockChildrenProps) { | ||
const isBackdropColorPassed = backdropColor !== undefined; | ||
if (children && React.isValidElement(children)) { | ||
const layout = { | ||
width: targetLayout?.width, | ||
height: targetLayout?.height, | ||
right: Constants.isRTL ? targetLayout?.x : undefined, | ||
top: targetLayout?.y, | ||
left: Constants.isRTL ? undefined : targetLayout?.x | ||
}; | ||
|
||
return ( | ||
<View style={[styles.mockChildrenContainer, layout, !isBackdropColorPassed && styles.hidden]}> | ||
{React.cloneElement<any>(children, { | ||
collapsable: false, | ||
key: 'mock', | ||
style: [children.props.style, styles.mockChildren] | ||
})} | ||
</View> | ||
); | ||
} | ||
return null; | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
hidden: {opacity: 0}, | ||
mockChildrenContainer: { | ||
position: 'absolute' | ||
}, | ||
mockChildren: { | ||
margin: undefined, | ||
marginVertical: undefined, | ||
marginHorizontal: undefined, | ||
marginTop: undefined, | ||
marginRight: undefined, | ||
marginBottom: undefined, | ||
marginLeft: undefined, | ||
|
||
top: undefined, | ||
left: undefined, | ||
right: undefined, | ||
bottom: undefined | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use 'message' so we can text the long massage here as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole idea of this use case was to test short message, that's why it's hard coded
I can change it, I just need the short variation of message to be extra short
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at it again, I prefer to keep it as it is