1.9 KB72 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {ForwardedRef} from 'react';
9import type {ReactProps} from './utils';
10
11import * as stylex from '@stylexjs/stylex';
12import {forwardRef} from 'react';
13import {textFieldStyles} from './TextField';
14
15const styles = stylex.create({
16 horizontalGrowContainer: {
17 display: 'inline-grid',
18 maxWidth: '600px',
19 alignItems: 'center',
20 '::after': {
21 width: 'auto',
22 minWidth: '1em',
23 content: 'attr(data-value)',
24 visibility: 'hidden',
25 whiteSpace: 'pre-wrap',
26 gridArea: '1 / 2',
27 height: '26px',
28 padding: '0 9px',
29 },
30 },
31
32 horizontalGrow: {
33 width: 'auto',
34 minWidth: '1em',
35 gridArea: '1 / 2',
36 },
37});
38
39/**
40 * Like a normal text field / {@link TextField}, but grows horizontally to fit the text.
41 */
42export const HorizontallyGrowingTextField = forwardRef(
43 (
44 props: ReactProps<HTMLInputElement> & {
45 value?: string;
46 placeholder?: string;
47 },
48 ref: ForwardedRef<HTMLInputElement>,
49 ) => {
50 const {onInput, ...otherProps} = props;
51
52 return (
53 <div {...stylex.props(styles.horizontalGrowContainer)} data-value={otherProps.value}>
54 <input
55 {...stylex.props(textFieldStyles.input, styles.horizontalGrow)}
56 type="text"
57 ref={ref}
58 onInput={e => {
59 if ((e.currentTarget.parentNode as HTMLDivElement)?.dataset) {
60 // Use `dataset` + `content: attr(data-value)` to size an ::after element,
61 // which auto-expands the containing div to fit the text.
62 (e.currentTarget.parentNode as HTMLDivElement).dataset.value = e.currentTarget.value;
63 }
64 onInput?.(e);
65 }}
66 {...otherProps}
67 />
68 </div>
69 );
70 },
71);
72