Skip to content

Commit

Permalink
Merge pull request #242 from elias-oxopia/master
Browse files Browse the repository at this point in the history
fixed checkbox: value prop updates internal state
  • Loading branch information
elias-oxopia committed Jun 23, 2023
2 parents c92af18 + 0371781 commit 15ecf4e
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 2 deletions.
21 changes: 20 additions & 1 deletion src/components/Checkbox/Checkbox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ route: /checkbox
---

import { Playground, Props } from 'docz';
import { Checkbox } from '../../index.ts'
import { Checkbox } from '../../index.ts';
import { Button } from '../..';

# Checkbox

Expand Down Expand Up @@ -47,6 +48,24 @@ A checkbox can be used enable an optional setting or feature.
<Checkbox label="Log" name="enabled-5" onChange={(event) => console.log(`LOGGER: ${event.target.checked}`)} />
</Playground>

### Updating initial state

<Playground>
{() => {
const [isChecked, setIsChecked] = React.useState(false);
const handleToggleClick = () => {
setIsChecked(!isChecked);
};
return (
<div style={{ display: 'flex', alignItems: 'center', gap: '20px' }}>
<Button onClick={handleToggleClick}>Toggle checkbox</Button>
<Checkbox label="Checkbox" name="enabled-6" value={isChecked} onChange={() => setIsChecked(!isChecked)} />
</div>
);
}}

</Playground>

## API

<Props of={Checkbox} />
16 changes: 16 additions & 0 deletions src/components/Checkbox/Checkbox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,20 @@ describe('Checkbox', () => {
// className in prop should be the last in the row
expect(renderedClassNames.indexOf(className)).toBe(renderedClassNames.length - 1);
});

test('value prop updates internal state', () => {
const { getByTestId, rerender } = render(<Checkbox {...defaultProps} value={false} />);
const checkbox = getByTestId('checkbox-enabled') as HTMLInputElement;

// Initial state should be unchecked
expect(checkbox.checked).toBe(false);

// Update value prop to true
rerender(<Checkbox {...defaultProps} value />);
expect(checkbox.checked).toBe(true);

// Update value prop back to false
rerender(<Checkbox {...defaultProps} value={false} />);
expect(checkbox.checked).toBe(false);
});
});
6 changes: 5 additions & 1 deletion src/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ChangeEventHandler, ReactNode, useState } from 'react';
import React, { ChangeEventHandler, ReactNode, useEffect, useState } from 'react';
import classNames from 'classnames';

import checkIcon from './check.svg';
Expand All @@ -20,6 +20,10 @@ const Checkbox = React.forwardRef<HTMLInputElement, Props>(
({ name, value, onChange, isDisabled = false, className, description, label }: Props, ref) => {
const [isChecked, setIsChecked] = useState<boolean>(value ?? false);

useEffect(() => {
setIsChecked(value ?? false);
}, [value]);

const labelClassNames = classNames(
cssReset.ventura,
styles.container,
Expand Down
21 changes: 21 additions & 0 deletions src/components/Modal/Modal.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ A modal is a dialog that appears on top of the main content to require user inte

</Playground>

### Modal max width

<Playground>
{() => {
const [isOpen, setIsOpen] = React.useState(false);
return (
<>
<Button onClick={() => setIsOpen(true)}>Open basic modal</Button>
<Modal title="This is the title" isOpen={isOpen} maxWidth="300px">
<span>Insert your text or form elements here</span>
<Modal.Footer>
<Button type='secondary' onClick={() => setIsOpen(false)}>Cancel</Button>
<Button onClick={() => 'do some logic here'}>Create</Button>
</Modal.Footer>
</Modal>
</>
);
}}

</Playground>

### Modal with async action

<Playground>
Expand Down
3 changes: 3 additions & 0 deletions src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Props = {
isOpen?: boolean;
onEscKeyDown?: () => void;
className?: string;
maxWidth?: string;
children?: ReactNode;
};

Expand All @@ -28,6 +29,7 @@ const Modal: React.FC<Props> & { Footer: typeof Footer } = ({
isOpen = false,
onEscKeyDown,
className,
maxWidth = '650px',
children,
}: Props) => {
const modalRef = React.useRef<HTMLDivElement>(null);
Expand All @@ -52,6 +54,7 @@ const Modal: React.FC<Props> & { Footer: typeof Footer } = ({
<article
ref={modalRef}
className={styles.modal}
style={{ maxWidth }}
onKeyDown={handleKeyDown}
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
tabIndex={0}
Expand Down

0 comments on commit 15ecf4e

Please sign in to comment.