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

View File

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

View File

@ -207,6 +207,8 @@
@apply @apply
text-[1rem] /* Prevent iOS auto-zoom behavior */ text-[1rem] /* Prevent iOS auto-zoom behavior */
read-only:cursor-default 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 { input[type=text], input[type=email], input[type=password], select {
@apply @apply