How to size react-native text components based on the text inside them? - react-native

I have two text components next to each other.
The first is supposed to expand as far as the text inside requires, and switch to ellipses when it would compress the second beyond a single line.
e.g.
Short text - 1 Alert |
Really really really long text is s... - 1 Alert |
Where the bar is the end of the available space.
What currently happens is that, regardless of the text in the alertProfile component, it always takes the same percentage of the screen, so I get a massive white space with short text. Meanwhile, the long text is truncated too early, so I end up with unused whitespace after the alert.
e.g.
Short text - 1 Alert |
Really really really... - 1 Alert |
My question is how do I get the long text to use as much space as possible, and the short text to use up as little as possible.
Code sample is below.
export function Heading(props) {
const { title, number } = props;
let alertCountText = " - 1 Alert";
if (number !== 1) {
alertCountText = ` - ${number} Alerts`;
}
return (
<View style={expandedStyle.header}>
<Text numberOfLines={1} style={[expandedStyle.alertTitle]}>
{title}
</Text>
<Text style={[expandedStyle.alertCount]}>
{alertCountText}
</Text>
</View>
);
}
const expandedStyle = StyleSheet.create({
header: {
flex: 1,
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center"
},
alertTitle: {
flex: 1,
fontFamily: "Lato-Bold",
fontSize: 16,
fontWeight: "bold",
fontStyle: "normal",
lineHeight: 18
},
alertCount: {
flex: 1,
fontFamily: "Lato-Regular",
fontSize: 14,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 14
}
});

Check this one. I am not so sure about the react-native. But this one works perfectly with the flexbox as per your requirement and so I am guessing it will be a valuable answer.
.wrapper {
display: inline-flex;
width: 70%;
border: 1px solid #ddd;
margin-bottom: 10px;
}
.text {
display: inline-block;
white-space: nowrap;
max-width: calc(100% - 100px);
overflow: hidden;
text-overflow: ellipsis;
}
.alert {
margin-left: 5px;
}
<div class='wrapper'>
<span class='text'>Text</span>
<span class='alert'>Alert</span>
</div>
<div class='wrapper'>
<span class='text'>Long Text</span>
<span class='alert'>Alert</span>
</div>
<div class='wrapper'>
<span class='text'>Really Really Really Really Long Text</span>
<span class='alert'>Alert</span>
</div>

Related

Disable or alter size change of TextInput in react-native-web

I'm looking for away to disable or alter the automatic zoom behavior I get when I select a TextInput in a react-native-web project. This is not an issue I'm having in react-native projects, only in projects using react-native-web. It throws off my layout because it zooms in when I select a TextInput, but never zooms back out, even when I navigate to another screen in the same project. I end up with a screen that is wider than the phone screen and has a scroll bar on bottom.
Here are the solutions I've tried so far that haven't worked for me:
Set height and maxHeight of the TextInput to the same value, and set width and maxWidth of the TextInput to the same value. This seems to be completely ignored and make no difference.
Contain the TextInputs within a View of set height/width and/or contain the whole component or screen within a View of set height/width. This doesn't work because TextInputs won't stay inside the boundaries of the View if it expands.
Put margin and padding around the main View of the screen. This will just compensate for the behavior instead of stopping it. It's not really sufficient.
I've looked at documentation for aspect ratio but I don't think this will help since as far as I can tell aspect ratio is not changing.
Here is an example of code that I'm having this issue with:
<TextInput style={styles.inputsTwo}
accessible={this.state.access}
placeholder="Email"
clearButtonMode="always"
onChangeText={text => this.setState({email: text})}
value={this.state.email}
/>
And here's my styling:
inputsTwo: {
textDecorationLine: 'underline',
marginBottom: 10,
textAlign: 'left',
marginLeft: 30,
borderBottomColor: 'rgb(85, 99, 255)',
borderBottomWidth: 2,
fontFamily: 'HelveticaNeue',
height: 48,
maxHeight: 48,
width: 300,
maxWidth: 300
},
When I open up developer tools in a browser I see that this is what react-native-web has translated this into:
<div dir="auto" data-focusable="true" tabindex="0" class="rn-borderTopWidth-13yce4e rn-
borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-
deolkf rn-display-1471scf rn-fontStyle-o11vmf rn-fontVariant-ebii48 rn-fontWeight-gul640
rn-lineHeight-t9a87b rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-
marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-
paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
style="align-items: center; color: rgb(255, 0, 0); font-family: Helvetica-Bold; font-size:
15px; justify-content: center; text-align: center; -webkit-box-align: center; -webkit-box-
pack: center;"></div>
<input placeholder="Email" autocapitalize="sentences" autocomplete="on" autocorrect="on"
dir="auto" spellcheck="true" type="text" data-focusable="true" class="rn-MozAppearance-
97bpaa rn-WebkitAppearance-n1uzsy rn-backgroundColor-1niwhzg rn-borderTopColor-nqhrom rn-
borderRightColor-1878er4 rn-borderLeftColor-fpul1g rn-borderTopLeftRadius-ou6ah9 rn-
borderTopRightRadius-t12b5v rn-borderBottomRightRadius-zmljjp rn-borderBottomLeftRadius-
pm2fo rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-
borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-
borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-fontSize-1b43r93 rn-paddingTop-wk8lta rn-
paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-resize-1dz5y72"
value="" style="border-bottom-color: rgb(85, 99, 255); border-bottom-width: 2px; font-
family: HelveticaNeue; height: 48px; margin-bottom: 10px; margin-left: 30px; max-height:
48px; max-width: 300px; text-align: left; text-decoration: underline; width: 300px;">
Any suggestions are appreciated. Thanks,
This answer has worked for me:
https://stackoverflow.com/a/16255670/9147743
I have modified it for my case like so:
inputsTwo: {
textDecorationLine: 'underline',
marginBottom: 10,
textAlign: 'left',
marginLeft: 30,
marginRight: 30,
borderBottomColor: 'rgb(85, 99, 255)',
borderBottomWidth: 2,
fontFamily: 'HelveticaNeue',
height: 48,
fontSize: 16
},

Change the color of a TextInput placeholder with Styled Components in React Native

How do you set the color of TextInput its placeholder with Styled Components in React Native?
I tried the following without any luck:
1.
const Input = styled.TextInput`
border: 1px solid green;
display: block;
margin: 0 0 1em;
::placeholder {
color: green;
}
`
2.
const Input = styled.TextInput`
border: 1px solid green;
display: block;
margin: 0 0 1em;
&::placeholder {
color: green;
}
`
The best way to make this:
export const Input = styled.TextInput.attrs({
placeholderTextColor: "red"
})`
background-color: "#000";
`;
you can try:
export const NewTodo = styled.input`
padding: 16px 16px 16px 60px;
font-weight: 300;
font-size: 15px;
::placeholder,
::-webkit-input-placeholder {
color: red;
}
:-ms-input-placeholder {
color: red;
}
`;
How do I style an input placeholder with Styled Components?
Adding on to #Fernando Pascoal Gomes's answer, if you wish to access the theme object, consider passing a function to .attrs() that returns an object that the component inherits for its props.
For your case, TextInput accepts a placeholderTextColor prop, so it might look like this:
const Input = styled.TextInput.attrs((props) => ({
placeholderTextColor: props.theme.palette.placeholderColor,
}))`
background-color: #fff;
color: #000;
...
`
You cannot style the placeholder color with styled-components directly, but you can pass the placeholderTextColor property to your styled Textinput.
Example:
const Input = styled.TextInput`
border: 1px solid green;
display: block;
margin: 0 0 1em;
`
and then inside your render function:
<Input placeholder="hello" placeholderTextColor="green" />
Output:
Working example:
https://snack.expo.io/rybp-nKaE
To change the textinputs placeholder's text color user prperty
"placeholderTextColor"
eg
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
placeholder = 'Enter text'
placeholderTextColor = 'red'
value={this.state.text}
/>

change label text from another controller in titanium alloy

I want to change text of label and make its visiblity true from another controller.
win_drawer_governmentNotification.xml
<Label id="filterCount" text="2"></Label>
win_drawer_governmentNotification.tss
"#filterCount":{
borderRadius: 100,
borderWidth: 1,
borderColor: "#f26418",
left: 46,
color: "#fff",
backgroundColor: "#f26418",
top: 15,
width: "8%",
textAlign: Titanium.UI.TEXT_ALIGNMENT_CENTER,
verticalAlign: Titanium.UI.TEXT_VERTICAL_ALIGNMENT_CENTER,
visible : false,
font: {
fontSize: Alloy.CFG.fonts.f_10,
fontFamily: Alloy.CFG.font_family.calibri
}
},
Now I want to change text of label filterCount from another controller in a function
I tried below code.
win_drawer_governmentNotification_filter.js
function applyFilter(e) {
var controller = Alloy.createController('win_drawer_governmentNotification');
Ti.API.info('controller = ' + controller);
var filterLabel = controller.filterCount;
Ti.API.info('filter label = ' + filterLabel);
Ti.App.fireEvent("win_drawer_governmentNotification:filterCount", {
text : "1",
visible : true
});
win_drawer_governmentNotification_filter.xml
<View id="view_apply_main" onClick="applyFilter">
<View id="view_apply">
<Label id="lbl_apply" text="APPLY FILTERS"/>
</View>
</View>
I tried different solutions from stackoverflow still haven't found solution like in
win_drawer_governmentNotification_filter.js
controller.filterCount.text = "1";
controller.filterCount.visible = true;
Can someone please help me what I am doing wrong? I am new to titanium.
Thanks in advance.

React-Native: How to change background second action

the problem is quite simple I think, but I can't seem to figure it out. I am using the react-native-router-flux library and the NativeBase library for the buttons.
This is my code:
<Button transparent onPress={Actions.MainOne } style={{ width: 50, height: 50 }} >
<Text>Option1</Text>
</Button>
<Button transparent onPress={Actions.MainTwo} style={{ width: 50, height: 50 }} >
<Text>Option2</Text>
</Button>
I want to change the background color of the button whenever i press it and it's active. And if I click another button, then the button I just pressed gets the background and the first button goes back to normal transparent background. I am not really sure how i can add two actions to the button. If anyone can assist I would appreciate it. I don't need to necessarily use the button library, so any ideas about this are welcome !
Thank you !
I use the flux-router to navigate through scenes. This is how I would change the background color of a button when pressed:
constructor() {
super();
state = {
color1: 'transparent',
color2: 'transparent',
}
}
setActive(button) {
if (button === 1) {
if (this.state.color1 === 'transparent') {
this.setState({
color1: 'red',
color2: 'transparent'
})
}
} else {
if (this.state.color2 === 'transparent') {
this.setState({
color2: 'red',
color1: 'transparent'
})
}
}
}
{ . . . }
<Button
onPress={this.setActive.bind(this, 1)}
style={{ width: 50, height: 50, backgroundColor: this.state.color1 }}
>
<Text>Option1</Text>
</Button>
<Button
this.setActive.bind(this, 2)
style={{ width: 50, height: 50, backgroundColor: this.state.color2 }}
>
<Text>Option2</Text>
</Button>

Issue with label alignment in titanium alloy

I have created custom check boxes in my application. I have no issue with check box and it's label if the label text is small. If the label text is large (more than a one line) the alignment is not showing properly.
Look at the above screenshot: the first option label text is "Please select the 2 primary reasons rating the program testing the program" and second option label text is "Question2". If the text in first label is small that is which fits in one line then the UI looks good. But If text is more than one line I am facing the above issue.
My code is as follows,
View:
<Label class="standardType1">Please select the 2 primary reasons rating the program?</Label>
<View class="checkBoxContainerView">
<Widget id="box1" src="checkbox" value="true"/>
<Label class="question1">Please select the 2 primary reasons rating the program testing the program</Label>
</View>
<View class="checkBoxContainerView">
<Widget id="box2" src="checkbox" value="true"/>
<Label class="question1">Question2</Label>
</View>
Style:
"#box1":
{
height: Ti.UI.SIZE,
width: Ti.UI.SIZE,
left:10
}
"#box2":
{
height: Ti.UI.SIZE,
width: Ti.UI.SIZE,
left:10
}
".question1":
{
top: 3,
left: 13,
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
color: '#fff',
font:{
fontSize: 16,
fontWeight: 'normal'
}
}
".checkBoxContainerView":
{
left: 15,
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
layout: 'horizontal'
}
Can any one help me with that? Even if label text is more than one line the height of the view should automatically increase and option should be view. Please help me.
After thinking a lot about your problem I experimented a little bit. I did not use the checkBox but tried to receive a proper alignment if the label is a multi-line label.
Xml:
<View id="temp" layout="horizontal" top="0" left="0">
<Label id="headline"/>
<Label id="description"/>
</View>
And my .tss:
"#headline": {
top: "0",
left: "0",
width: "50%",
text: "Headline",
font: {
fontSize: 20
}
}
"#description": {
left: "0",
width: "50%",
text: "Your long text here",
font: {
fontSize: 16
}
}
As you can see I did not specify any height or width for my container (not defined in the .tss but in the xml) and only set a width parameter for my labels. You should consider to use 10-20% for your checkBoxes and the rest for your label. Do not specify any height parameters since the system will do this automatically.