Something went wrong. Try again.
a tool for shared writing and social publishing
Something went wrong. Try again.
2.4 kB · 89 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990"use client";import { useEffect, useRef, useState, type JSX } from "react";import { onMouseDown } from "src/utils/iosInputMouseDown";import { isIOS } from "src/utils/isDevice";import { focusElement } from "src/utils/focusElement";
export const Input = ( props: { textarea?: boolean; } & JSX.IntrinsicElements["input"] & JSX.IntrinsicElements["textarea"],) => { let { textarea, ...inputProps } = props; let ref = useRef<HTMLInputElement>(null); useEffect(() => { if (!isIOS()) return; if (props.autoFocus) { focusElement(ref.current); } }, [props.autoFocus]);
if (textarea) return <textarea {...inputProps} />; return ( <input {...inputProps} autoFocus={isIOS() ? false : props.autoFocus} ref={ref} onMouseDown={onMouseDown} /> );};
export const AsyncValueInput = ( props: { textarea?: boolean; } & JSX.IntrinsicElements["input"] & JSX.IntrinsicElements["textarea"],) => { let [intermediateState, setIntermediateState] = useState( props.value as string, );
useEffect(() => { setIntermediateState(props.value as string); }, [props.value]);
return ( <Input {...props} value={intermediateState} onChange={async (e) => { if (!props.onChange) return; setIntermediateState(e.currentTarget.value); await Promise.all([ props.onChange(e as React.ChangeEvent<HTMLInputElement>), ]); }} /> );};
export const InputWithLabel = ( props: { label: string; textarea?: boolean; } & JSX.IntrinsicElements["input"] & JSX.IntrinsicElements["textarea"],) => { let { label, textarea, ...inputProps } = props; let style = ` appearance-none resize-none w-full bg-transparent outline-hidden focus:outline-0 font-normal not-italic text-base text-primary disabled:text-tertiary disabled:cursor-not-allowed ${props.className}`; return ( <label className={`input-with-border flex flex-col gap-px text-sm text-tertiary font-bold italic leading-tight py-1! px-[6px]! ${props.disabled && "bg-border-light! cursor-not-allowed! hover:border-border! text-tertiary!"}`} > {props.label} {textarea ? ( <textarea {...inputProps} className={style} /> ) : ( <Input {...inputProps} className={style} /> )} </label> );};