In my React/NextJS app, I have this simple input:
Components:
Search > SearchSelect > ExchangeInfo.tsx:
Search.tsx
<SearchSelect
assets={assets}
selected={selected}
exchange={exchange}
exchanges={exchanges}
fetching={fetching}
aggregate={aggregate}
checkAggregate={this.handleCheckAggregate}
enterPosition={this.handleEnterPosition}
exchangeSelect={this.handleExchangeSelect}
/>
//... the function:
@bind
handleEnterPosition(position: number) {
this.setState({ position })
}
SearchSelect
<SearchExchanges
selected={selected}
exchange={exchange}
exchanges={exchanges}
checkAggregate={checkAggregate}
aggregate={aggregate}
enterPosition={this.props.enterPosition}
exchangeSelect={this.props.exchangeSelect}
/>
ExchangeInfo
import React from 'react'
import { bind } from 'decko'
import { IAsset, IMarketAsset } from '../../shared/types'
import { EnterPositionStyle } from '../../styles'
interface IPropsInfo {
asset: IAsset
}
interface IPropsCount {
exchanges: IMarketAsset[]
}
interface IPropsPosition {
asset: IAsset
enterPosition(position: number): void
}
export const ExchangeSelectInfo = (props: IPropsInfo) =>
<h2>Exchanges with <span>{props.asset.currency}</span> denominated in BTC, ETH, USD, USDC, or USDT will be listed above. Otherwise the asset's price will be an aggregate of supported exchanges.</h2>
export const ExchangesCount = (props: IPropsCount) => {
const { exchanges } = props
const pural = exchanges.length > 1 && 's'
return (<option key={'default'}>({exchanges.length}) Exchange{pural}:</option>)
}
export class EnterPosition extends React.Component<IPropsPosition> {
render() {
const { asset } = this.props
return (
<EnterPositionStyle>
<h2>Enter your <span>{asset.currency}</span> position in order to add asset to your Portfolio. Or add the asset to your Watchlist.</h2>
<input type="number" placeholder="Enter Position" onChange={this.handleChange} />
</EnterPositionStyle>
)
}
@bind
private handleChange(event: React.FormEvent<HTMLInputElement>) {
const target = event.target as HTMLInputElement
const parsed = parseFloat(target.value)
const position = Number.isNaN(parsed) ? 0 : parsed
console.log('target.value', target.value);
this.props.enterPosition(position)
}
}
It works on the web fine: https://moon.holdings (Or https://dev.moon.holdings) (Click on the + select an asset, then Aggregate then try to enter in position.
However on mobile it only lets me put in an actual phone number, and typing does not change the input :(
Seems that it's an iPhone issue, my Android friends can add in positions, but not my iPhone ones. Strange....
I added an input to the root component / container and it works... seems like the problem is that the input I'm using is embedded 3 components down. Or something related to that.
Believe it or not, this is a css problem. Saw your page, you have these css on inputs that cause problem in safari.
user-select: none;
-webkit-user-select: none;
Remove them, and your inputs will get back to work. In case you have difficulty removing them, override with
-webkit-user-select: text;
user-select: text;