/** * Copyright (c) TonTech. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ import { useCallback, useLayoutEffect, useRef, useState } from 'react'; import type { FC, ComponentProps } from 'react'; import clsx from 'clsx'; import styles from './centered-amount-input.module.css'; const MIN_FONT_SCALE = 0.5; export interface CenteredAmountInputProps extends ComponentProps<'div'> { value: string; onValueChange: (value: string) => void; ticker?: string; symbol?: string; placeholder?: string; } export const CenteredAmountInput: FC = ({ value, onValueChange, ticker, symbol, placeholder = '0', className, ...props }) => { const wrapperRef = useRef(null); const measureRowRef = useRef(null); const mirrorRef = useRef(null); const inputRef = useRef(null); const [inputWidth, setInputWidth] = useState(undefined); const [fontScale, setFontScale] = useState(1); const adjustSize = useCallback(() => { const wrapper = wrapperRef.current; const measureRow = measureRowRef.current; const mirror = mirrorRef.current; if (!wrapper || !measureRow || !mirror) return; const contentWidth = measureRow.offsetWidth; const availableWidth = wrapper.clientWidth - 4; let scale = 1; if (contentWidth > 0 && contentWidth > availableWidth) { scale = Math.max(MIN_FONT_SCALE, availableWidth / contentWidth); } setFontScale(scale); setInputWidth(mirror.offsetWidth * scale + 4); }, []); useLayoutEffect(adjustSize, [value, placeholder, symbol, ticker, adjustSize]); useLayoutEffect(() => { const wrapper = wrapperRef.current; if (!wrapper) return; const observer = new ResizeObserver(adjustSize); observer.observe(wrapper); return () => observer.disconnect(); }, [adjustSize]); const scaledInputFontSize = fontScale < 1 ? `calc(var(--ta-input-xl-size) * ${fontScale})` : undefined; const scaledTickerFontSize = fontScale < 1 ? `calc(var(--ta-input-xl-symbol-size) * ${fontScale})` : undefined; return (
inputRef.current?.focus()} {...props} >
{symbol && ( {symbol} )} onValueChange(e.target.value)} style={{ width: inputWidth ? `${inputWidth}px` : undefined, fontSize: scaledInputFontSize, }} /> {ticker && ( {ticker} )}
); };