Fix forms for Tailwind 4

This commit is contained in:
Sam Becker 2025-02-08 21:47:31 -06:00
parent 696f1b9f2a
commit 6eab91025b
3 changed files with 39 additions and 27 deletions

View File

@ -1,11 +1,12 @@
'use client';
import { LegacyRef } from 'react';
import { Ref } from 'react';
import { useFormStatus } from 'react-dom';
import Spinner from './Spinner';
import { clsx } from 'clsx/lite';
import { FieldSetType, AnnotatedTag } from '@/photo/form';
import TagInput from './TagInput';
import { FiChevronDown } from 'react-icons/fi';
export default function FieldSetWithStatus({
id,
@ -44,7 +45,7 @@ export default function FieldSetWithStatus({
readOnly?: boolean
capitalize?: boolean
type?: FieldSetType
inputRef?: LegacyRef<HTMLInputElement>
inputRef?: Ref<HTMLInputElement>
accessory?: React.ReactNode
hideLabel?: boolean
}) {
@ -89,28 +90,37 @@ export default function FieldSetWithStatus({
</label>}
<div className="flex gap-2">
{selectOptions
? <select
id={id}
name={id}
value={value}
onChange={e => onChange?.(e.target.value)}
className={clsx(
'w-full',
clsx(Boolean(error) && 'error'),
// Use special class because `select` can't be readonly
readOnly || pending && 'disabled-select',
)}
>
{selectOptionsDefaultLabel &&
<option value="">{selectOptionsDefaultLabel}</option>}
{selectOptions.map(({ value: optionValue, label: optionLabel }) =>
<option
key={optionValue}
value={optionValue}
>
{optionLabel}
</option>)}
</select>
? <div className="relative w-full">
<select
id={id}
name={id}
value={value}
onChange={e => onChange?.(e.target.value)}
className={clsx(
'w-full',
clsx(Boolean(error) && 'error'),
// Use special class because `select` can't be readonly
readOnly || pending && 'disabled-select',
)}
>
{selectOptionsDefaultLabel &&
<option value="">{selectOptionsDefaultLabel}</option>}
{selectOptions.map(({ value: optionValue, label: optionLabel }) =>
<option
key={optionValue}
value={optionValue}
>
{optionLabel}
</option>)}
</select>
<div className={clsx(
'absolute top-0 right-3 z-10 pointer-events-none',
'flex h-full items-center',
'text-extra-dim text-2xl',
)}>
<FiChevronDown />
</div>
</div>
: tagOptions
? <TagInput
id={id}

View File

@ -226,8 +226,8 @@ export default function TagInput({
className={clsx(
className,
'w-full control px-2! py-2!',
'outline-1 outline-blue-600',
'group-focus-within:outline group-active:outline',
'-outline-offset-2 outline-blue-600',
'group-focus-within:outline-2 ',
'inline-flex flex-wrap items-center gap-2',
readOnly && 'cursor-not-allowed',
readOnly && 'bg-gray-100 dark:bg-gray-900 dark:text-gray-400',
@ -259,7 +259,7 @@ export default function TagInput({
type="text"
className={clsx(
'grow min-w-0! p-0! -my-2 text-xl',
'border-none! ring-transparent!',
'outline-hidden border-none',
'placeholder:text-dim placeholder:text-[14px]',
'placeholder:translate-x-[2px]',
'placeholder:translate-y-[-1.5px]',

View File

@ -207,6 +207,8 @@
@apply
text-[1rem] /* Prevent iOS auto-zoom behavior */
read-only:cursor-default
outline-blue-600 ring-blue-600 appearance-none
focus:outline-2 -outline-offset-2 focus:ring-0
}
input[type=text], input[type=email], input[type=password], select {
@apply