Finalize checkbox presentation/behavior
This commit is contained in:
parent
a6228ce888
commit
f9b6d7f485
@ -1,5 +1,5 @@
|
||||
import clsx from 'clsx/lite';
|
||||
import { InputHTMLAttributes, ReactNode, Ref } from 'react';
|
||||
import { InputHTMLAttributes, ReactNode, RefObject } from 'react';
|
||||
import { ImCheckmark } from 'react-icons/im';
|
||||
|
||||
const boxStyles = clsx(
|
||||
@ -14,18 +14,21 @@ export default function Checkbox({
|
||||
accessory,
|
||||
type: _type,
|
||||
...props
|
||||
}: InputHTMLAttributes<HTMLInputElement> & {
|
||||
ref?: Ref<HTMLInputElement>
|
||||
}: Omit<InputHTMLAttributes<HTMLInputElement>, 'ref'> & {
|
||||
ref?: RefObject<HTMLInputElement | null>
|
||||
accessory?: ReactNode
|
||||
}) {
|
||||
return (
|
||||
<span className={clsx(
|
||||
'relative inline-flex items-center justify-center',
|
||||
'size-5',
|
||||
props.readOnly
|
||||
? 'cursor-not-allowed'
|
||||
: 'group-has-active:opacity-70',
|
||||
)}>
|
||||
<span
|
||||
className={clsx(
|
||||
'relative inline-flex items-center justify-center',
|
||||
'size-5',
|
||||
props.readOnly
|
||||
? 'cursor-not-allowed'
|
||||
: 'group-has-active:opacity-70',
|
||||
)}
|
||||
onClick={() => ref?.current?.click()}
|
||||
>
|
||||
{accessory
|
||||
? accessory
|
||||
: props.checked
|
||||
@ -34,12 +37,15 @@ export default function Checkbox({
|
||||
'border-transparent',
|
||||
props.readOnly
|
||||
? 'bg-gray-300 dark:bg-gray-700'
|
||||
: 'bg-blue-600',
|
||||
: 'bg-black',
|
||||
)}>
|
||||
<ImCheckmark className={clsx(
|
||||
'text-white text-[11px]',
|
||||
props.readOnly && 'dark:text-gray-400',
|
||||
)} />
|
||||
<ImCheckmark
|
||||
size={12}
|
||||
className={clsx(
|
||||
'text-white',
|
||||
props.readOnly && 'dark:text-gray-400',
|
||||
)}
|
||||
/>
|
||||
</span>
|
||||
: <span className={clsx(
|
||||
boxStyles,
|
||||
@ -50,7 +56,7 @@ export default function Checkbox({
|
||||
ref={ref}
|
||||
type="checkbox"
|
||||
className={clsx(
|
||||
'absolute inset-0 invisible',
|
||||
'absolute inset-0 opacity-0! size-5',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Ref, InputHTMLAttributes } from 'react';
|
||||
import { InputHTMLAttributes, useRef, RefObject } from 'react';
|
||||
import { useFormStatus } from 'react-dom';
|
||||
import Spinner from './Spinner';
|
||||
import { clsx } from 'clsx/lite';
|
||||
@ -31,7 +31,7 @@ export default function FieldSetWithStatus({
|
||||
spellCheck,
|
||||
capitalize,
|
||||
type = 'text',
|
||||
inputRef,
|
||||
inputRef: inputRefProp,
|
||||
accessory,
|
||||
hideLabel,
|
||||
}: {
|
||||
@ -55,10 +55,14 @@ export default function FieldSetWithStatus({
|
||||
spellCheck?: boolean
|
||||
capitalize?: boolean
|
||||
type?: FieldSetType
|
||||
inputRef?: Ref<HTMLInputElement>
|
||||
inputRef?: RefObject<HTMLInputElement | null>
|
||||
accessory?: React.ReactNode
|
||||
hideLabel?: boolean
|
||||
}) {
|
||||
const inputRefInternal = useRef<HTMLInputElement>(null);
|
||||
|
||||
const inputRef = inputRefProp ?? inputRefInternal;
|
||||
|
||||
const id = _id || parameterize(label);
|
||||
|
||||
const { pending } = useFormStatus();
|
||||
@ -68,7 +72,9 @@ export default function FieldSetWithStatus({
|
||||
name: id,
|
||||
type,
|
||||
value,
|
||||
checked: type === 'checkbox' ? value === 'true' : undefined,
|
||||
checked: type === 'checkbox'
|
||||
? value === 'true' ? true : false
|
||||
: undefined,
|
||||
placeholder,
|
||||
onChange: e => onChange?.(type === 'checkbox'
|
||||
? e.target.value === 'true' ? 'false' : 'true'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user