Port some stuff from sync PR

This commit is contained in:
Gregory Schier
2024-12-05 11:27:49 -08:00
parent 2b61257e50
commit a79578142d
5 changed files with 57 additions and 51 deletions

View File

@@ -1,51 +1,54 @@
import classNames from 'classnames';
import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
import type { HTMLAttributes } from 'react';
import { useCallback, useMemo, useRef, useState } from 'react';
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
import { IconButton } from './IconButton';
import type { InputProps } from './Input';
import { HStack } from './Stacks';
export type PlainInputProps = Omit<InputProps, 'wrapLines' | 'onKeyDown' | 'type'> & {
type?: 'text' | 'password' | 'number';
step?: number;
};
export type PlainInputProps = Omit<InputProps, 'wrapLines' | 'onKeyDown' | 'type'> &
Pick<HTMLAttributes<HTMLInputElement>, 'onKeyDownCapture'> & {
type?: 'text' | 'password' | 'number';
step?: number;
};
export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function Input(
{
className,
containerClassName,
defaultValue,
forceUpdateKey,
hideLabel,
label,
labelClassName,
labelPosition = 'top',
leftSlot,
name,
onBlur,
onChange,
onFocus,
onPaste,
placeholder,
require,
rightSlot,
size = 'md',
type = 'text',
validate,
autoSelect,
...props
}: PlainInputProps,
ref,
) {
export function PlainInput({
className,
containerClassName,
defaultValue,
forceUpdateKey,
hideLabel,
label,
labelClassName,
labelPosition = 'top',
leftSlot,
name,
onBlur,
onChange,
onFocus,
onPaste,
placeholder,
require,
rightSlot,
size = 'md',
type = 'text',
validate,
autoSelect,
step,
autoFocus,
readOnly,
}: PlainInputProps) {
const [obscured, setObscured] = useStateWithDeps(type === 'password', [type]);
const [currentValue, setCurrentValue] = useState(defaultValue ?? '');
const [focused, setFocused] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const handleFocus = useCallback(() => {
setFocused(true);
if (autoSelect) {
inputRef.current?.select();
textareaRef.current?.select();
}
onFocus?.();
}, [autoSelect, onFocus]);
@@ -56,9 +59,9 @@ export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function
}, [onBlur]);
const id = `input-${name}`;
const inputClassName = classNames(
const commonClassName = classNames(
className,
'!bg-transparent min-w-0 h-auto w-full focus:outline-none placeholder:text-placeholder',
'!bg-transparent min-w-0 w-full focus:outline-none placeholder:text-placeholder',
'px-2 text-xs font-mono cursor-text',
);
@@ -122,7 +125,7 @@ export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function
)}
>
<input
ref={ref}
ref={inputRef}
key={forceUpdateKey}
id={id}
type={type === 'password' && !obscured ? 'text' : type}
@@ -133,10 +136,12 @@ export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function
autoCorrect="off"
onChange={(e) => handleChange(e.target.value)}
onPaste={(e) => onPaste?.(e.clipboardData.getData('Text'))}
className={inputClassName}
className={classNames(commonClassName, 'h-auto')}
onFocus={handleFocus}
onBlur={handleBlur}
{...props}
autoFocus={autoFocus}
step={step}
readOnly={readOnly}
/>
</HStack>
{type === 'password' && (
@@ -154,7 +159,7 @@ export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function
</HStack>
</div>
);
});
}
function validateRequire(v: string) {
return v.length > 0;