aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/instant/src/components/asset_amount_input.tsx15
-rw-r--r--packages/instant/src/components/scaling_amount_input.tsx8
-rw-r--r--packages/instant/src/components/scaling_input.tsx73
3 files changed, 57 insertions, 39 deletions
diff --git a/packages/instant/src/components/asset_amount_input.tsx b/packages/instant/src/components/asset_amount_input.tsx
index 0b22c889c..beb21a4cf 100644
--- a/packages/instant/src/components/asset_amount_input.tsx
+++ b/packages/instant/src/components/asset_amount_input.tsx
@@ -41,8 +41,9 @@ export class AssetAmountInput extends React.Component<AssetAmountInputProps, Ass
{...rest}
startWidthCh={3.5}
endWidthCh={5}
- fontSizePx={this.state.currentFontSizePx}
+ maxFontSizePx={this.props.startingFontSizePx}
onChange={this._handleChange}
+ onFontSizeChange={this._handleFontSizeChange}
/>
</Container>
<Container display="inline-block" marginLeft="10px">
@@ -57,12 +58,12 @@ export class AssetAmountInput extends React.Component<AssetAmountInputProps, Ass
</Container>
);
}
- private readonly _handleChange = (value?: BigNumber, fontSize?: number): void => {
+ private readonly _handleChange = (value?: BigNumber): void => {
this.props.onChange(value, this.props.asset);
- if (!_.isUndefined(fontSize)) {
- this.setState({
- currentFontSizePx: fontSize,
- });
- }
+ };
+ private readonly _handleFontSizeChange = (fontSizePx: number): void => {
+ this.setState({
+ currentFontSizePx: fontSizePx,
+ });
};
}
diff --git a/packages/instant/src/components/scaling_amount_input.tsx b/packages/instant/src/components/scaling_amount_input.tsx
index a0b7b74af..83375af00 100644
--- a/packages/instant/src/components/scaling_amount_input.tsx
+++ b/packages/instant/src/components/scaling_amount_input.tsx
@@ -9,12 +9,13 @@ import { ScalingInput } from './scaling_input';
import { Container, Text } from './ui';
export interface ScalingAmountInputProps {
- fontSizePx: number;
+ maxFontSizePx: number;
startWidthCh: number;
endWidthCh: number;
fontColor?: ColorOption;
value?: BigNumber;
onChange: (value?: BigNumber, fontSize?: number) => void;
+ onFontSizeChange: (fontSizePx: number) => void;
}
export class ScalingAmountInput extends React.Component<ScalingAmountInputProps> {
@@ -23,12 +24,13 @@ export class ScalingAmountInput extends React.Component<ScalingAmountInputProps>
onFontSizeChange: util.boundNoop,
};
public render(): React.ReactNode {
- const { startWidthCh, endWidthCh, fontColor, fontSizePx, value } = this.props;
+ const { startWidthCh, endWidthCh, fontColor, maxFontSizePx, value, onFontSizeChange } = this.props;
return (
<ScalingInput
startWidthCh={startWidthCh}
endWidthCh={endWidthCh}
- fontSizePx={fontSizePx}
+ maxFontSizePx={maxFontSizePx}
+ onFontSizeChange={onFontSizeChange}
fontColor={fontColor}
onChange={this._handleChange}
value={!_.isUndefined(value) ? value.toString() : ''}
diff --git a/packages/instant/src/components/scaling_input.tsx b/packages/instant/src/components/scaling_input.tsx
index a2c4ba342..7824c10f9 100644
--- a/packages/instant/src/components/scaling_input.tsx
+++ b/packages/instant/src/components/scaling_input.tsx
@@ -17,21 +17,29 @@ export enum ScalingInputPhase {
export interface ScalingInputProps {
startWidthCh: number;
endWidthCh: number;
- fontSizePx: number;
+ maxFontSizePx: number;
value?: string;
- onChange: (event: React.ChangeEvent<HTMLInputElement>, fontSize: number) => void;
+ onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
+ onFontSizeChange: (fontSizePx: number) => void;
fontColor?: ColorOption;
placeholder?: string;
+ maxLength?: number;
}
-export interface ScalingInputProps {
+export interface ScalingInputState {
fixedWidthInPxIfExists?: number;
}
-export class ScalingInput extends React.Component<ScalingInputProps> {
+export interface ScalingInputSnapshot {
+ inputWidthPx: number;
+}
+// This is a magic number that was determined experimentally.
+const percentageToReduceByPerCharacter = 0.15;
+export class ScalingInput extends React.Component<ScalingInputProps, ScalingInputState> {
public static defaultProps = {
onChange: util.boundNoop,
onFontSizeChange: util.boundNoop,
+ maxLength: 10,
};
public state = {
fixedWidthInPxIfExists: undefined,
@@ -50,13 +58,35 @@ export class ScalingInput extends React.Component<ScalingInputProps> {
const { value, startWidthCh, endWidthCh } = props;
return ScalingInput.getPhase(startWidthCh, endWidthCh, value);
}
- public componentDidUpdate(prevProps: ScalingInputProps): void {
+ public static calculateFontSize(props: ScalingInputProps): number {
+ const { startWidthCh, endWidthCh, value, maxFontSizePx } = props;
+ const phase = ScalingInput.getPhase(startWidthCh, endWidthCh, value);
+ if (_.isUndefined(value) || phase !== ScalingInputPhase.End) {
+ return maxFontSizePx;
+ }
+ const charactersOverMax = value.length - endWidthCh;
+ const scalingFactor = (1 - percentageToReduceByPerCharacter) ** charactersOverMax;
+ const fontSize = scalingFactor * maxFontSizePx;
+ return fontSize;
+ }
+ public getSnapshotBeforeUpdate(): ScalingInputSnapshot {
+ return {
+ inputWidthPx: this._getInputWidthInPx(),
+ };
+ }
+ public componentDidUpdate(
+ prevProps: ScalingInputProps,
+ prevState: ScalingInputState,
+ snapshot: ScalingInputSnapshot,
+ ): void {
const prevPhase = ScalingInput.getPhaseFromProps(prevProps);
const curPhase = ScalingInput.getPhaseFromProps(this.props);
+ const prevFontSize = ScalingInput.calculateFontSize(prevProps);
+ const curFontSize = ScalingInput.calculateFontSize(this.props);
// if we went from anything else to end, fix to the current width as it shouldn't change as we grow
if (prevPhase !== ScalingInputPhase.End && curPhase === ScalingInputPhase.End) {
this.setState({
- fixedWidthInPxIfExists: this._getInputWidthInPx(),
+ fixedWidthInPxIfExists: snapshot.inputWidthPx,
});
}
// if we end from end to to anything else, un-fix the width
@@ -65,19 +95,24 @@ export class ScalingInput extends React.Component<ScalingInputProps> {
fixedWidthInPxIfExists: undefined,
});
}
+ // If font size has changed, notify.
+ if (prevFontSize !== curFontSize) {
+ this.props.onFontSizeChange(curFontSize);
+ }
}
public render(): React.ReactNode {
- const { fontColor, onChange, placeholder, value } = this.props;
+ const { fontColor, onChange, placeholder, value, maxLength } = this.props;
const phase = ScalingInput.getPhaseFromProps(this.props);
return (
<Input
ref={this._inputRef as any}
fontColor={fontColor}
- onChange={this._handleChange}
+ onChange={onChange}
value={value}
placeholder={placeholder}
- fontSize={`${this.props.fontSizePx}px`}
+ fontSize={`${ScalingInput.calculateFontSize(this.props)}px`}
width={this._calculateWidth()}
+ maxLength={maxLength}
/>
);
}
@@ -108,24 +143,4 @@ export class ScalingInput extends React.Component<ScalingInputProps> {
}
return (ref as any).getBoundingClientRect().width;
};
- private readonly _calculateNextFontSize = (
- currentFontSizePx: number,
- value: string,
- startWidthCh: number,
- endWidthCh: number,
- ): number => {
- const phase = ScalingInput.getPhase(startWidthCh, endWidthCh, value);
- if (_.isUndefined(value) || phase !== ScalingInputPhase.End) {
- return currentFontSizePx;
- }
- const charactersOverMax = value.length - endWidthCh;
- const pixelsToReduceFontSizeBy = charactersOverMax * 5;
- const fontSize = currentFontSizePx - pixelsToReduceFontSizeBy;
- return fontSize;
- };
- private readonly _handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- const value = event.target.value;
- const { fontSizePx, startWidthCh, endWidthCh } = this.props;
- this.props.onChange(event, this._calculateNextFontSize(fontSizePx, value, startWidthCh, endWidthCh));
- };
}