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

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
},

Related

How can I use my spritesheet of icons in react native?

How can I properly use sprite sheets in react-native? Or do people typically load icons separately and not use sprite sheets? Mind you this is not sprites for animation, just pure icons.
For example here is my sheet...
And here is the css for one icon...
.Sprite {
background-image: url(./assets/images/spritesheet.png);
background-repeat: no-repeat;
display: inline-block;
}
.IconMenu30px {
width: 30px;
height: 30px;
background-position: -53px -5px;
}
And I tried to translate this into React Native like this...
<Image source={require("../assets/images/spritesheet.png")} style={styles.menuIcon} />
const styles = StyleSheet.create({
menuIcon: {
width: 30,
height: 30,
},
})
But apparently there is no background position attribute in React Native.
Did you try
<ImageBackground />
This might help with your issue

How to increase clickable area surrounding a Vuetify v-slider's nob?

How do you increase the clickable area surrounding the nobs of Vuetify's v-slider component?
I would like to do this in order to make it easier for users to 'grab the nob' and control the slider, particularly for the sake of mobile UX.
Here is a method to increase the clickable area of the draggable v-slider and v-range-slider nobs using CSS. It should be noted that, as of February 2021, v-slider and v-range-slider do not yet have built-in props to control this functionality.
My answer is based on this github comment (note: it is worth reading this entire github issue thread, as it concerns the OP's question).
<style scoped lang="scss">
.my-slider-class >>> .v-slider__thumb:after {
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
content: '';
color: inherit;
width: 400%;
height: 400%;
border-radius: 50%;
background: transparent;
position: absolute;
left: -150%;
top: -150%;
}
.my-slider-class >>> .v-slider__thumb:before {
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
content: '';
color: inherit;
width: 200%;
height: 200%;
border-radius: 50%;
background: currentColor;
opacity: 0.3;
position: absolute;
left: -50%;
top: -50%;
transform: scale(0.1);
pointer-events: none;
}
</style>

How can my splash screen be implemented into Vue?

Side note:
The splash screen code below from my Vue app is a view file not a component. Also I'm suing Vue router.
So below is my code, this is a splash screen using Gsap that has a callback function that I can later put in a route that goes to '/' which is the Home view.
How can I have this view showed first when launching the Vue app? And then once the animation is completed the callback will direct the user to the home page. Also one more thing, I'm not sure how this would work, but I want to make sure that once a user goes to the home page and some reason they refresh they don't have to see the splash screen again. How can that also be achieved?
Note: I did try to mess with the index.js under router but nothing worked and redirect never allowed the user to get to the home page.
HTML:
<template>
<div class="module_wrapper">
<h1 ref="title">Welcome</h1>
<div ref="module" class="module">
<div class="top_wrapper">
<div ref="box1" class="box box_1"></div>
</div>
<div class="bottom_wrapper">
<div ref="box2" class="box box_2"></div>
<div ref="box3" class="box box_4"></div>
<div ref="box4" class="box box_5"></div>
<div ref="box5" class="box box_3"></div>
</div>
</div>
</div>
</template>
JavaScript:
import { TimelineLite, Back } from 'gsap';
export default {
methods: {
onCompleteAll () {
console.log('done');
}
},
mounted () {
const {module} = this.$refs;
const {title} = this.$refs;
const {box1} = this.$refs;
const {box2} = this.$refs;
const {box3} = this.$refs;
const {box4} = this.$refs;
const {box5} = this.$refs;
const {top} = this.$refs;
const {bottom} = this.$refs;
const timeline = new TimelineLite({onComplete: this.onCompleteAll});
timeline.to(module, 1.3, {scale: 1, ease: 'elastic.out(1, 0.5)',})
.to(box1, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box2, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box3, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box4, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box5, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(top, 0.4, {marginLeft: 10 + '%', ease: Back.easeInOut}, '-=0.2')
.to(bottom, 0.4, {marginLeft: 10 + '%', ease: Back.easeInOut}, '-=0.2')
.to(title, 0.4, {
translateY: 0,
opacity: 1,
ease: Back.easeInOut
}, '-=0.8');
}
};
CSS:
#app {
font-family: Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
html {
font-size: 100%;
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
outline: none;
}
html {
width: 100%;
height: 100%;
overflow: hidden;
}
html, body {
transform: perspective(1px) scale(1) translateZ(0);
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
}
body {
background: radial-gradient(#656565, #000000);
width: 100%;
height: 100%;
}
.module_wrapper {
color: white;
text-align: center;
height: 13.4375rem;
width: 18.75rem;
margin: 0;
padding: 0;
border-radius: 0.75rem;
}
h1 {
font-size: 1.4375rem;
font-weight: 500;
color: #D9D9D9;
letter-spacing: 0.5rem;
cursor: default;
opacity: 0;
transform: translateY(10px);
}
.module {
background-color: #fff;
border-radius: 0.75rem;
width: 18.75rem;
height: 11.375rem;
margin: 0;
padding: 0;
transform: scale(0);
}
.top_wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 50%;
padding: 0 1.25rem;
}
.bottom_wrapper {
display: flex;
align-items: center;
padding: 0 1.25rem;
justify-content: space-evenly;
height: 50%;
}
.box {
background-color: #D9D9D9;
border-radius: 0.4375rem;
margin: 0;
padding: 0;
transform: translateY(-40px);
opacity: 0;
}
.box_1 {
width: 14.375rem;
height: 3.6rem;
}
.box_2, .box_3, .box_4, .box_5 {
width: 2.875rem;
height: 3.25rem;
}
You will need to add a Navigation Guard to your / route.
The general idea is:
-Check if the user has already authenticated
-if they have, call next()
-if they haven't, redirect them to the login/splash page: next('login')
There are a few options, but I think the best one will be to control the component's visibility in App.vue rather than inside the component. When the animation is over emit something to the parent, listen to that thing in the parent, and change the component visibility.
In order to display animation only one time, use session storage or local storage, and as the first job on page load, check if storage has anything about that. If it doesn't play your animation.

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

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>

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.