SteffeyDev / react-native-popover-view

A well-tested, adaptable, lightweight <Popover> component for react-native
MIT License
613 stars 92 forks source link

Display popover view not render correctly using mode: 'tooltip' and placement: 'bottom' in android #151

Closed hildebrandjp closed 1 year ago

hildebrandjp commented 1 year ago

Describe the bug I'm trying to implement a tooltip that can be clickable outside anytime. I want to set the tooltip mode and placement bottom. But the tooltip render is truncated. I think it depends on parent element. I tried to use popoverStyle to change the minHeight and height but still not working.

Device/Setup Info:

Screenshots image

Debug Output

LOG [2022-12-06T02:12:09.282Z] componentWillUnmount LOG [2022-12-06T02:12:09.302Z] animateOut - isMounted LOG [2022-12-06T02:12:09.304Z] getTranslateOrigin - popoverSize: {"width":221.81817626953125,"height":14.727272987365723} LOG [2022-12-06T02:12:09.305Z] getTranslateOrigin - anchorPoint: {"x":372.18180751800537,"y":43.272735595703125} LOG [2022-12-06T02:12:09.406Z] Tearing down keyboard listeners LOG [2022-12-06T02:12:11.133Z] calculateRectFromRef - waiting for ref LOG [2022-12-06T02:12:11.133Z] calculateRectFromRef - waiting for ref to move from: {"x":0,"y":0,"width":0,"height":0} LOG [2022-12-06T02:12:11.305Z] calculateRectFromRef - calculated Rect: {"x":0,"y":118.18181610107422,"width":0,"height":0} LOG [2022-12-06T02:12:11.359Z] setDefaultDisplayArea - newDisplayArea: {"x":0,"y":0.000055486505743829184,"width":392.7272644042969,"height":61.818180084228516} LOG [2022-12-06T02:12:11.372Z] setDefaultDisplayArea - displayAreaOffset: {"x":0,"y":118.18181610107422} LOG [2022-12-06T02:12:11.405Z] [BasePopover] componentDidUpdate - changedProps: ["displayArea"] LOG [2022-12-06T02:12:11.407Z] componentDidUpdate - isVisible not changed, handling other changes
LOG [2022-12-06T02:12:11.408Z] handleChange - no requestedContentSize, exiting... LOG [2022-12-06T02:12:11.410Z] calculateRectFromRef - waiting for ref LOG [2022-12-06T02:12:11.410Z] calculateRectFromRef - waiting for ref to move from: {"x":0,"y":118.18181610107422,"width":0,"height":0} LOG [2022-12-06T02:12:11.418Z] measureContent - new requestedContentSize: {"width":221.81817626953125,"height":38.181819915771484} (used to be null) LOG [2022-12-06T02:12:11.449Z] handleChange - waiting 100ms to accumulate all changes LOG [2022-12-06T02:12:11.557Z] handleChange - requestedContentSize: {"width":221.81817626953125,"height":38.181819915771484} LOG [2022-12-06T02:12:11.557Z] handleChange - displayArea: {"x":0,"y":0.000055486505743829184,"width":392.7272644042969,"height":61.818180084228516} LOG [2022-12-06T02:12:11.557Z] handleChange - fromRect: {"x":0,"y":118.18181610107422,"width":0,"height":0} LOG [2022-12-06T02:12:11.558Z] handleChange - placement: "bottom" LOG [2022-12-06T02:12:11.559Z] computeGeometry - initial chosen geometry: {"popoverOrigin":{"x":10,"y":51.81823557073426},"anchorPoint":{"x":17,"y":118.18181610107422},"placement":"bottom","forcedContentSize":{"width":372.7272644042969,"height":-66.36358053033996},"viewLargerThanDisplayArea":{"height":true,"width":false}} LOG [2022-12-06T02:12:11.559Z] computeGeometry - final chosen geometry: {"popoverOrigin":{"x":10,"y":51.81823557073426},"anchorPoint":{"x":17,"y":118.18181610107422},"placement":"bottom","forcedContentSize":{"width":372.7272644042969,"height":-66.36358053033996},"viewLargerThanDisplayArea":{"height":true,"width":false}} LOG [2022-12-06T02:12:11.580Z] handleChange - delaying showing popover because viewLargerThanDisplayArea LOG [2022-12-06T02:12:11.583Z] calculateRectFromRef - calculated Rect: {"x":359.6363525390625,"y":16.00000762939453,"width":25.090909957885742,"height":27.272727966308594} LOG [2022-12-06T02:12:11.611Z] [BasePopover] componentDidUpdate - changedProps: ["fromRect"] LOG [2022-12-06T02:12:11.613Z] componentDidUpdate - isVisible not changed, handling other changes
LOG [2022-12-06T02:12:11.614Z] handleChange - waiting 100ms to accumulate all changes LOG [2022-12-06T02:12:11.659Z] measureContent - new requestedContentSize: {"width":221.81817626953125,"height":38.54545593261719} (used to be {"width":221.81817626953125,"height":38.181819915771484}) LOG [2022-12-06T02:12:11.688Z] handleChange - waiting 100ms to accumulate all changes LOG [2022-12-06T02:12:11.806Z] handleChange - requestedContentSize: {"width":221.81817626953125,"height":38.54545593261719} LOG [2022-12-06T02:12:11.807Z] handleChange - displayArea: {"x":0,"y":0.000055486505743829184,"width":392.7272644042969,"height":61.818180084228516} LOG [2022-12-06T02:12:11.807Z] handleChange - fromRect: {"x":359.6363525390625,"y":16.00000762939453,"width":25.090909957885742,"height":27.272727966308594} } LOG [2022-12-06T02:12:12.050Z] animateIn - translatePoint: {"x":160.90908813476562,"y":43.272735595703125} LOG [2022-12-06T02:12:12.063Z] Setting up keyboard listeners LOG [2022-12-06T02:12:12.189Z] animateIn - onOpenComplete - Calculated Popover Rect: {"x":161.09091186523438,"y":167.63636779785156,"width":221.81817626953125,"height":8.727272987365723} LOG [2022-12-06T02:12:12.191Z] animateIn - onOpenComplete - Calculated Arrow Rect: {"x":365.4545593261719,"y":161.4545440673828,"width":16,"height":8}

Code

passwordChange.js

const PasswordChange = () => {

const [isShowPopover, setIsShowPopover] = useState(true); const [idpopOver, setIdpopOver] = useState(1);

const onUpdatePassword = (values) => { console.log({values}); }

const iconAlertElement = (errorText, errors, id) => ( <> <RNPopover mode='tooltip' isVisible={isShowPopover && errors && (id === idpopOver)} onRequestClose={() => setIsShowPopover(false)} verticalOffset={null} offset={0} from = {(

)}>
    <View style={{overflow: 'visible', backgroundColor: '#151515'}} className="px-3 py-2 relative">
      <Text style={{color: '#fff'}}>{errorText}</Text>
    </View>
</RNPopover>
</>
);

return (

onUpdatePassword(values)} validateOnChange={false} > { ({handleChange, handleSubmit, values, errors}) => ( <> { setIdpopOver(1); setIsShowPopover(true); }} style={{position: 'relative'}} value={values.initialPassword} onChangeText={handleChange('initialPassword')} className={`bg-white py-4 text-right ${errors.initialPassword && !values.initialPassword ? 'pr-8': 'pr-5'} border-b border-gray-300 mb-0.5`} placeholder='6文字以上半角英数字' secureTextEntry /> { errors.initialPassword && !values.initialPassword ? iconAlertElement(errors.initialPassword, errors.initialPassword && !values.initialPassword, 1) : null } パスワード
      <View className='relative'>
        <TextInput 
          onFocus={(e) => {setIdpopOver(2); setIsShowPopover(true);}}
          value={values.newPassword}
          onChangeText={handleChange('newPassword')}
          className={`bg-white py-4 text-right ${errors.newPassword && !errors.initialPassword && !values.newPassword ? 'pr-8': 'pr-5'} border-b border-gray-300 mb-0.5`}
          placeholder='6文字以上半角英数字'
          secureTextEntry
          />
          { 
            errors.newPassword && !errors.initialPassword && !values.newPassword ? 
              <View style={{}}>
                iconAlertElement(errors.newPassword,  errors.newPassword && !errors.initialPassword && !values.newPassword, 2)
              </View> : null 
          }
        <Text className='absolute pl-4 top-5'>新しいパスワード</Text>
      </View>
      <View className='relative'>
        <TextInput 
          onFocus={(e) => {setIdpopOver(3); setIsShowPopover(true);}}
          value={values.confirmNewPassword}
          onChangeText={handleChange('confirmNewPassword')}
          className={`bg-white py-4 text-right ${errors.confirmNewPassword && !errors.newPassword && !errors.initialPassword ? 'pr-8': 'pr-5'} border-b border-gray-300 mb-0.5`}
          placeholder='もう一度パスワードを入力し...'
          secureTextEntry
          />
          { 
              errors.confirmNewPassword && !errors.newPassword && !errors.initialPassword ? 
            iconAlertElement(errors.confirmNewPassword,  
              errors.confirmNewPassword && !errors.newPassword && !errors.initialPassword, 3) : null 
          }
        <Text className='absolute pl-4 top-5'>確認用パスワード</Text>
      </View>
      <View className='flex-row self-center items-center mt-4'>
        <TouchableOpacity onPress={(e) => {handleSubmit(e); setIsShowPopover(true)}} className='py-2 w-11/12 bg-primary rounded-full'>
            <Text className='text-white text-center'>変更する</Text>
        </TouchableOpacity>
      </View>
      <View className='mt-5'>
        <Text className='text-center'>パスワードをお忘れの方はこちら</Text>
      </View>
    </> )}

  </Formik>
</View>

) }

RNPopover.js export default function RNPopover({ children, from=null, onRequestClose=null, isVisible=false, placement="bottom", arrowSize={width: 14, height: 6}, mode=PopoverMode.RN_MODAL, offset=-10, popoverStyle=null, verticalOffset=Platform.OS === 'android' ? -StatusBar.currentHeight : 0 }) { return ( <> <Popover debug={true} backgroundStyle={{backgroundColor: 'transparent', opacity: 0}} arrowSize={arrowSize} popoverStyle={{backgroundColor: 'red', borderTopColor: 'red', borderTopWidth: 3, borderRadius: 0, padding: 0, margin: 0, ...popoverStyle}} animationConfig={{duration:0}} mode={mode} placement={placement} offset={offset} verticalOffset={verticalOffset} isVisible={isVisible} onRequestClose={() => onRequestClose()} from = {from}> {children} </Popover> </> ) }

SteffeyDev commented 1 year ago

Please review this section of the documentation, make sure you have a good understanding of how React Native renders views when using Tooltip mode.

It's not very clear what your issue is. The image you attached is cropped and it's hard to see what it is showing, and the code you included is unformatted so I can't read it well. If you improve the code formatting and are more specific about what your issue is, I may be able to help.

hildebrandjp commented 1 year ago

I already solve the issue using onCloseComplete callback set custom minHeight to popoverStyle prop and it works. Thank you