Skip to content

Commit

Permalink
Merge pull request #276 from reaviz/syang/267/checkbox-bug
Browse files Browse the repository at this point in the history
#267 Fix checked checkbox in Dialog
  • Loading branch information
amcdnl authored Feb 7, 2025
2 parents 7072145 + e33c8bd commit c9abdc8
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 8 deletions.
40 changes: 39 additions & 1 deletion src/form/Checkbox/Checkbox.story.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, { Fragment, useState } from 'react';
import { Button } from '@/elements/Button';
import { Dialog, useDialog } from '@/layers/Dialog';
import { Fragment, useState } from 'react';
import { Checkbox } from './Checkbox';

export default {
Expand Down Expand Up @@ -158,3 +160,39 @@ export const CustomLabel = () => {
/>
);
};

export const WithDialog = () => {
const { isOpen, setOpen } = useDialog();
const [checked, setChecked] = useState(true);

return (
<main className="flex flex-col items-center gap-8 py-16 max-w-[1280px] mx-auto">
<div className="flex flex-row items-center gap-6">
<Button onClick={() => setOpen(true)}>Open</Button>
</div>
<Dialog
size={600}
open={isOpen}
onClose={() => setOpen(false)}
header="Checkbox test"
>
{() => (
<div>
<Checkbox
label="Test checkbox"
checked={checked}
onChange={setChecked}
/>
<br />
<Checkbox
label="Test indeterminate state"
checked={checked}
onChange={setChecked}
intermediate
/>
</div>
)}
</Dialog>
</main>
);
};
21 changes: 16 additions & 5 deletions src/form/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useComponentTheme } from '@/utils';
import { motion, useMotionValue, useTransform } from 'motion/react';
import React, {
FC,
forwardRef,
LegacyRef,
ReactNode,
useCallback
useCallback,
useEffect,
useState
} from 'react';
import { motion, useMotionValue, useTransform } from 'motion/react';
import { twMerge } from 'tailwind-merge';
import { CheckboxTheme } from './CheckboxTheme';
import { useComponentTheme } from '@/utils';
import { CheckboxLabel } from './CheckboxLabel';
import { CheckboxTheme } from './CheckboxTheme';

export interface CheckboxProps {
/**
Expand Down Expand Up @@ -121,6 +123,16 @@ export const Checkbox: FC<CheckboxProps & CheckboxRef> = forwardRef(
const pathLength = useMotionValue(0);
const opacity = useTransform(pathLength, [0.05, 0.15], [0, 1]);

// If the checkbox is inside a dialog, the animation will not work.
// This is a workaround to force the animation to work by triggering
// a re-render once after initial mount
const [_, setForceAnimation] = useState<boolean>(false);
useEffect(() => {
if (checked || intermediate) {
setForceAnimation(true);
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps

const checkVariants = {
pressed: (isChecked: boolean) => ({ pathLength: isChecked ? 0.85 : 0.3 }),
checked: { pathLength: 1 },
Expand Down Expand Up @@ -177,7 +189,6 @@ export const Checkbox: FC<CheckboxProps & CheckboxRef> = forwardRef(
}}
>
<motion.svg
initial={checked ? 'checked' : 'unchecked'}
animate={checked ? 'checked' : 'unchecked'}
whileHover={!disabled ? 'hover' : undefined}
whileTap={!disabled ? 'pressed' : undefined}
Expand Down
3 changes: 1 addition & 2 deletions src/form/Input/DebouncedInput/DebouncedInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ export const DebouncedInput = forwardRef<InputRef, DebouncedInputProps>(
{ debounce = 100, value, onChange, onValueChange, ...rest },
ref: Ref<InputRef>
) => {
// eslint-disable-next-line no-undef
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const [internalValue, setInternalValue] = useState<
string | number | readonly string[]
>(value);
Expand Down

0 comments on commit c9abdc8

Please sign in to comment.