Styled-components react native - Text Input onBlur not working - react-native

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.

Related

Combining selector and prop conditions in emotion

I have the following setup in my code (simplified example):
import styled from '#emotion/styled'
const Container = styled.div<{value?: string}>`
&:focus-within {
border-color: red;
}
${() => Input} {
border-color: ${({value}) => value && 'red'};
}
`
const Input = styled.input`
border: 0;
`
const MyComponent = ({value}: {value?: string}) => (
<Container value={value}>
<Input />
</Container>
)
The gist of it is this:
The input's border is set on its Container.
I want to set the border red when (1) the input is active, or (2) the input has a value.
I am currently achieving this with the code above.
My question is:
Is it possible to combine the selector (&:focus-inside) and the prop (value) somehow in emotion in a single conditional statement so that I don't repeat the styling code twice?

Style React Native switch component

I'm developing a mobile application using React Native. This project needs a custom button to provides a boolean type of input. But I have no idea how to create this kind of custom component for that. I did a research and I try to create this custom button with a react-native switch (import { Switch } from 'react-native';). But seems like It is difficult to style.
I'm not sure what would be the best way to achieve that? Using the switch component? Please help me to find a better solution or new approach for this.
Thank you.
I have made a custom switch in react native and You can do the styling in it a source code is given below -
import React from 'react'
import { Text, TouchableOpacity } from 'react-native'
import styled from 'styled-components/native'
class App extends React.Component {
state = {
active: false
}
handleOFF = () => {
this.setState({
active: false
});
}
handleOn = () => {
this.setState({
active: true
});
}
render() {
return (
<MainView>
<Label>
<LabelOff onPress={this.handleOFF} active={this.state.active} activeOpacity={0.8}>
<Off>OFF</Off>
</LabelOff>
<LabelOn onPress={this.handleOn} active={this.state.active} activeOpacity={0.8}>
<On>ON</On>
</LabelOn>
</Label>
</MainView>
)
}
}
const MainView = styled.View`
margin:50px;
`
const Label = styled.View`
height:60px;
width:240px;
flex-direction:row;
justify-content:space-around;
align-items:center;
background-color:transparent;
`
const LabelOff = styled.TouchableOpacity`
height:60px;
width:120px;
background-color:${props => props.active ? 'transparent' : '#cb6161'};
border:2px solid #cb6161;
border-right-width:0px;
align-items:center;
justify-content:space-around;
`
const LabelOn = styled.TouchableOpacity`
height:60px;
width:120px;
background-color:${props => props.active ? '#55acee' : 'transparent'};
border:2px solid #55acee;
border-left-width:0px;
align-items:center;
justify-content:space-around;
`
const Off = styled.Text`
font-size:22px;
`
const On = styled.Text`
font-size:22px;
`
export default App
Custom switch is done !

How can i change the hover style of a PrimaryButton in Fluent UI?

I am currently trying to re-style a Fabric UI Button in React by changing its shape, background color and hovering color. I managed to change the first two, but i'm still having troubles in accessing the hover color, since the selectors property does not seem to work.
My code is the following:
import React, { Component, Props } from 'react';
import { PrimaryButton as FluentPrimaryButton, IButtonStyles, IStyle} from 'office-ui-fabric-react';
interface MyPrimaryButtonProps {
label?: string
}
const MyPrimaryButton = ({label}: MyPrimaryButtonProps) => {
const styles: IButtonStyles = {
root: [
{
fontSize: '16px',
background: '#525CA3 ',
border: '1px solid #525CA3',
borderRadius: '20px',
padding: '0px 30px',
height: '40px',
selectors: { // <---
':hover': { // <--- this part doesn't work.
backgroundColor: 'red' // <---
},
}
}
]
};
return (
<div>
<FluentPrimaryButton styles={styles} text={label} />
</div>
);
};
export default MyPrimaryButton;
I get a custom button, but still the hover color remains default blue, instead of switching to red.
You can change the styling of the button when hovered like this:
const btnStyles = {
rootHovered: {
backgroundColor: "red"
}
};
// ...
<FluentPrimaryButton text = {label} styles = {btnStyles} />;

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

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

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.