How to make react-native-elements Tooltip size dynamic based on its content? - react-native

The React Native Elements Tooltip (docs here) requires you to pass in the width and height property for the tooltip, but I want to create a generic tooltip button that can receive any element as its popover prop.
The following example is what I have, but it uses the default size set to the tooltip by the React Native Element library:
import React from 'react'
import { Tooltip } from 'react-native-elements'
import styled from 'styled-components'
const Container = styled.View`
justify-content: center;
align-items: center;
background-color: #aaf;
height: 25px;
width: 25px;
border-radius: 12.5px;
`
const Icon = styled.Text``
export default function TooltipButton({ tooltip }) {
return (
<Tooltip popover={tooltip}>
<Container>
<Icon>?</Icon>
</Container>
</Tooltip>
)
}
When the content is bigger than the default size it looks like this.
I Don't want to have to pass a fixed size as prop to this component, I would like it to have a tooltip size depending on it's content.

After some time trying to figure this out, I managed to do a somewhat autosize tooltip button that receives a content element as a prop (tooltip) and resizes itself based on its content.
The only way I got it to work properly was to set an initial size bigger than the content (500x500) and add more size to it (+30).
import React, { useState } from 'react'
import { Tooltip } from 'react-native-elements'
import styled from 'styled-components'
const Container = styled.View`
justify-content: center;
align-items: center;
background-color: #aaf;
height: 25px;
width: 25px;
border-radius: 12.5px;
`
const Icon = styled.Text``
export default function TooltipButton({ tooltip }) {
const [tooltipSize, setTooltipSize] = useState({ w: 500, h: 500 })
const tooltipClone = React.cloneElement(
tooltip,
{ onLayout: (e) => setTooltipSize({ w: e.nativeEvent.layout.width, h: e.nativeEvent.layout.height }) }
)
return (
<Tooltip
popover={tooltipClone}
width={tooltipSize.w + 30}
height={tooltipSize.h + 30}
>
<Container>
<Icon>?</Icon>
</Container>
</Tooltip>
)
}
End result looks like this.

I guess it's enough to add 20 units to width and height. That's required because the default style applied to the Tooltip component adds a padding of 10, see here.

It seems that using null forces height and width to take as much space as the contents need!
height={null} // using height={null} seems to look good
width={null} // using width={200} seems to look better than null
Source of this hint: ToolTip in react native

Related

How style child element from parent in react native styled-components

I have container with child
<Container>
{[1, 2, 3].map((el) => {
return (
<Container2 key={el}>
<Text>{el}</Text>
</Container2>
)
})}
</Container>
and when I trying style child with help of selector it doesn't work for me.
const Container = styled(Block)`
flex-direction: column;
& > * {
background: black;
flex: initial;
margin-right: 0;
border-bottom-width: 5px;
border-bottom-color: white;
}
`
As I understood selectors don't work in native, but how we can style child from parent
in this case?
It's not possible
See: how do you style Text children in React Native with styled components?
You can just create a stylesheet and add a class for those children components, then add the style tag to it, like so:
<Container2 key={el} style={styles.yourCreatedClass}>
<Text>{el}</Text>
</Container2>

Styled-components react native - Text Input onBlur not working

I'm fairly new to styled-components in react native. I'm creating a custom TextInput component. I want to add an event of onBlur to change a piece of state. However onBlur is never triggered.
import React, { useCallback } from 'react'
const TextField = styled.TextField`
margin-top: 6px;
font-size: 14px;
color: '#000';
padding: 16px 15px;
border: 0.8px solid;
background-color: '#fff';
`
const Input = ({
editable,
...rest
}) => {
const handleOnFocus = useCallback(() => {
console.log('focus')
}, [])
const handleOnBlur = useCallback(() => {
console.log('blur')
}, [])
return (
<TextField
onFocus={handleOnFocus}
onBlur={handleOnBlur}
editable={editable}
{...rest}
/>
)
}
export default Input
as per guidelines of Textinput in
React Native Textinput
editable should be true to called blur, because if your input is editable is false then you can not focus that element and without focused element onBlur never triggered.
Found my issue. It's a stupid mistake. Happened to be passing the prop onBlur to the Input component which was overriding the onBlur I was trying to set on the TextField styled-component.

Customize TextInput Label of the react-native-paper in the case of React Native Web

I'm working with the React Native Web and React Native Paper library with Styled Components. Basically I would like to customize the TextInput inner components: Label and html input
The questions are:
1) How to change Label styles? eg. width\size\color, etc. ?
2) How to change html input styles? I want to set outline: none to prevent the blue border show on focus in the case of browser.
I understand that in the case of native we don't have html and the native-web transpiles it.
And I can't understand how to catch the nested label component to change its styles. Because I want to show gray label when non-filled, violet when filled and the Input text should be black.
In the case of the web, it's trivial but in the case of native, I don't know how to handle it.
So is that possible at all?
Thanks for any help. Here is the code example
import React from 'react';
import {
View,
Platform,
} from 'react-native';
import {
TextInput as NativePaperInput,
withTheme,
} from 'react-native-paper';
import styled from 'styled-components/native';
const NativePaperInputThemed = withTheme(NativePaperInput);
export const TextInputStyled = styled(NativePaperInputThemed)`
${(props: any) => {
return `
outline: none; // doesn't work
input: { outline: none; } // doesn't work
& input: { outline: none; } // doesn't work
// Label change style ?
color: ${props.theme.theme10x.palette.typography.placeholder}; // doesn't work
border-color: '#f92a2a8a'; // doesn't work
height: 52px;
`;
}
}
`;
P.S. Basically even colors and fontFamily doesn't work somehow
label={<Text style={{fontSize: 20}}>{t('PersonalDetailsYuvitalOrg:editInput.firstName')}</Text>}
Some guy tried to change label style manually, the maintainer reponse:
You can pass fontSize via style prop. However it will affect both
label and input text. There is no way to change only one of them.
https://github.com/callstack/react-native-paper/issues/1505
You can pass a component for the label prop. For Example:
export const Input = styled(TextInput).attrs({
dense: true,
activeUnderlineColor: theme.colors.ui.blueDark,
label: <Text style={{fontSize: 50}}>My Custom Label</Text>
})`
width: 100%;
height: 50px;
font-size: 16px;
`
However, I have not looked for a way to control the scale when the animation occurs.

How to replace default Quill.js dropdown.svg with Font Awesome icon?

Background
We are currently using vue-quill-editor vue-quill-editor to integrate a text editor into a Vue.js app.
As we are using Font Awesome in the app, I have replaced each default toolbar icon with the Font Awesome equivalent.
main.js
import VueQuillEditor from 'vue-quill-editor';
import Quill from 'quill';
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import '#/assets/scss/main.scss';
const icons = Quill.import('ui/icons');
icons['bold'] = '<i class="fa fa-bold" aria-hidden="true"></i>';
icons['italic'] = '<i class="fa fa-italic" aria-hidden="true"></i>';
The only icon that I have not been able to change in this way is the picker/dropdown icon, as it is not in icons.js.
Question
What is the best way to replace the default picker/dropdown icon with a Font Awesome equivalent ( e.g., <i class="fa fa-chevron-down" aria-hidden="true"></i>)?
Thanks!
Thanks for the above solution, Patel.
As it happens, I came up with a simpler solution that does not require creating a custom select option.
I just removed the default svg and added the new icon using :after:
.ql-picker-label {
svg {
width: 0px !important;
}
}
.ql-header,
.ql-size {
.ql-picker-label:after {
color: $black !important;
content: '\f078';
font-family: 'FontAwesome';
position: absolute;
top: 1px !important;
right: 0;
}
}
It seems to work pretty well and will, of course, apply to all such elements.
You can't change drop-down directly but yah you can add custom select option and apply style on it.
Codepen - https://codepen.io/Pratik__007/pen/QWbyWoE

React Native: Fit Text's content inside View without specific size

I have an Image and a Text component inside a Container with flex-direction row that fits 100% of my screen. The Text component has no size specified to it, neither does the Container.
When I have a single word that is to big, the Text component cuts the end of it's content with "-"; When I have a bunch of small words, the Text component cuts it's content after a given word; When I have a single small word (my use case) the Text component cuts the end of the word in a random character, even though it has plenty of space to render the text.
Here are my code snippets:
import React from 'react';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { Container, Top, Logo, Title } from './styles';
import logo from '../../assets/Nubank_Logo.png';
export default function Header() {
return (
<Container>
<Top>
<Logo source={logo} />
<Title>Bruno</Title>
</Top>
<Icon name="keyboard-arrow-down" size={20} color="#fff" />
</Container>
);
}
import styled from 'styled-components/native';
export const Container = styled.View`
align-items: center;
padding: 40px 0 30px 0;
`;
export const Top = styled.View`
flex-direction: row;
align-items: center;
margin-bottom: 10px;
`;
export const Logo = styled.Image``;
export const Title = styled.Text`
font-size: 18px;
color: #fff;
font-weight: bold;
margin-left: 8px;
`;
And here is an screenshot of the result of this code
After a lot of research I found the cause to my problem.
I have a OnePlus 6 phone with android 9. I was using OnePlus Slate as my phone's default font.
The problem is that React Native Text component cuts the end of the text depending on the font you are using. It's a bug that has been around for a while and they still didn't find a solution for it. Here are some issues on their page on github:
https://github.com/facebook/react-native/issues/15114
https://github.com/facebook/react-native/issues/17026
https://github.com/facebook/react-native/issues/17629
and the comment in which I found the solution:
https://github.com/facebook/react-native/issues/15114#issuecomment-520112872
My solution
Since my phone has the option to change the system font family I just went and changed it to Roboto, as a test. In a real scenario you would need to change your app's default font family to Roboto.