Skip to content

Commit

Permalink
OPHJOD-261: Add RadioButton & RadioButtonGroup
Browse files Browse the repository at this point in the history
  • Loading branch information
ketsappi committed Mar 27, 2024
1 parent 13b3c43 commit 25cc2ff
Show file tree
Hide file tree
Showing 7 changed files with 317 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/components/RadioButton/RadioButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { render, screen, cleanup } from '@testing-library/react';
import { afterEach, describe, expect, it, test, vi } from 'vitest';
import { RadioButtonGroup } from './RadioButtonGroup';
import { RadioButton } from './RadioButton';
import '@testing-library/jest-dom/vitest';
import React from 'react';

afterEach(() => {
cleanup();
});

const Wrapper = ({ children }: { children: React.ReactNode }) => {
return (
<RadioButtonGroup label="" value="" onChange={vi.fn()}>
{children}
</RadioButtonGroup>
);
};

describe('Snapshot testing', () => {
test('Default', () => {
const { container } = render(
<Wrapper>
<RadioButton label="A" value="a" />
</Wrapper>,
);
expect(container.firstChild).toMatchSnapshot();
});
});

describe('RadioButton', () => {
it('renders the label correctly', () => {
render(
<Wrapper>
<RadioButton label="Option 1" value="option1" />
</Wrapper>,
);
expect(screen.getByText('Option 1')).toBeInTheDocument();
});
});
41 changes: 41 additions & 0 deletions lib/components/RadioButton/RadioButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { RadioGroup } from '@headlessui/react';

export interface RadioButtonProps {
/** Text for the component */
label: string;
value: string;
className?: string;
}

export const RadioButton = ({ label, value, className }: RadioButtonProps) => {
return (
<RadioGroup.Option value={value} className={`${className ? className : ''}`.trim()}>
{({ checked }) => (
<div className="flex-start flex space-x-3">
{checked ? <CheckedIcon /> : <UncheckedIcon />}
<span className="flex items-center text-[#4D5358]">{label}</span>
</div>
)}
</RadioGroup.Option>
);
};

const CheckedIcon = () => {
return (
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g>
<circle cx="15.6992" cy="16.1349" r="10.6992" stroke="#4D5358" strokeWidth="10" />
</g>
</svg>
);
};

const UncheckedIcon = () => {
return (
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g>
<circle cx="15.6992" cy="16.5333" r="15.6992" fill="white" />
</g>
</svg>
);
};
58 changes: 58 additions & 0 deletions lib/components/RadioButton/RadioButtonGroup.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { render, screen, cleanup } from '@testing-library/react';
import { afterEach, describe, expect, it, test, vi } from 'vitest';
import userEvent from '@testing-library/user-event';
import { RadioButtonGroup } from './RadioButtonGroup';
import { RadioButton } from './RadioButton';
import '@testing-library/jest-dom/vitest';

afterEach(() => {
cleanup();
});

describe('Snapshot testing', () => {
test('Default', () => {
const { container } = render(
<RadioButtonGroup label="A" value="a" onChange={vi.fn()}>
<RadioButton value="option1" label="Option 1" />
</RadioButtonGroup>,
);
expect(container.firstChild).toMatchSnapshot();
});
});

describe('RadioButtonGroup', () => {
it('renders the label correctly', () => {
render(
<RadioButtonGroup label="Test Label" value="" onChange={vi.fn()}>
<RadioButton value="option1" label="Option 1" />
</RadioButtonGroup>,
);

expect(screen.getByText('Test Label')).toBeInTheDocument();
});

it('renders the children correctly', () => {
render(
<RadioButtonGroup label="Test Label" value="" onChange={vi.fn()}>
<RadioButton value="option1" label="Option 1" />
</RadioButtonGroup>,
);

expect(screen.getByText('Option 1')).toBeInTheDocument();
});

it('calls the onChange callback when a RadioButton is selected', async () => {
const user = userEvent.setup();
const mockOnChange = vi.fn();

render(
<RadioButtonGroup label="Test Label" value="" onChange={mockOnChange}>
<RadioButton value="option1" label="Option 1" />
</RadioButtonGroup>,
);

const radioButton = screen.getByText('Option 1');
await user.click(radioButton);
expect(mockOnChange).toHaveBeenCalledTimes(1);
});
});
25 changes: 25 additions & 0 deletions lib/components/RadioButton/RadioButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { RadioGroup } from '@headlessui/react';

export interface RadioButtonGroupProps {
/** Text for the component */
label: string;

value: string;
onChange: (newValue: string) => void;
children: React.ReactNode;
className?: string;
}

export const RadioButtonGroup = ({ label, value, onChange, children, className }: RadioButtonGroupProps) => {
return (
<RadioGroup
value={value}
onChange={onChange}
className={`${className ? className : ''} flex flex-col space-y-2`.trim()}
>
<RadioGroup.Label className="text-[#4D5358]">{label}</RadioGroup.Label>
{children}
</RadioGroup>
);
};
99 changes: 99 additions & 0 deletions lib/components/RadioButton/__snapshots__/RadioButton.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Snapshot testing > Base button 1`] = `
<div
aria-labelledby="headlessui-label-:r1:"
class="flex flex-col space-y-2"
id="headlessui-radiogroup-:r0:"
role="radiogroup"
>
<label
class="text-[#4D5358]"
id="headlessui-label-:r1:"
role="none"
/>
<div
aria-checked="false"
class=""
data-headlessui-state=""
id="headlessui-radiogroup-option-:r2:"
role="radio"
tabindex="0"
>
<div
class="flex-start flex space-x-3"
>
<svg
fill="none"
height="32"
viewBox="0 0 32 32"
width="32"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<circle
cx="15.6992"
cy="16.5333"
fill="white"
r="15.6992"
/>
</g>
</svg>
<span
class="flex items-center text-[#4D5358]"
>
A
</span>
</div>
</div>
</div>
`;

exports[`Snapshot testing > Default 1`] = `
<div
aria-labelledby="headlessui-label-:r1:"
class="flex flex-col space-y-2"
id="headlessui-radiogroup-:r0:"
role="radiogroup"
>
<label
class="text-[#4D5358]"
id="headlessui-label-:r1:"
role="none"
/>
<div
aria-checked="false"
class=""
data-headlessui-state=""
id="headlessui-radiogroup-option-:r2:"
role="radio"
tabindex="0"
>
<div
class="flex-start flex space-x-3"
>
<svg
fill="none"
height="32"
viewBox="0 0 32 32"
width="32"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<circle
cx="15.6992"
cy="16.5333"
fill="white"
r="15.6992"
/>
</g>
</svg>
<span
class="flex items-center text-[#4D5358]"
>
A
</span>
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Snapshot testing > Default 1`] = `
<div
aria-labelledby="headlessui-label-:r1:"
class="flex flex-col space-y-2"
id="headlessui-radiogroup-:r0:"
role="radiogroup"
>
<label
class="text-[#4D5358]"
id="headlessui-label-:r1:"
role="none"
>
A
</label>
<div
aria-checked="false"
class=""
data-headlessui-state=""
id="headlessui-radiogroup-option-:r2:"
role="radio"
tabindex="0"
>
<div
class="flex-start flex space-x-3"
>
<svg
fill="none"
height="32"
viewBox="0 0 32 32"
width="32"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<circle
cx="15.6992"
cy="16.5333"
fill="white"
r="15.6992"
/>
</g>
</svg>
<span
class="flex items-center text-[#4D5358]"
>
Option 1
</span>
</div>
</div>
</div>
`;
2 changes: 2 additions & 0 deletions lib/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ import './index.css';
export { Button } from './components/Button/Button';
export { DropdownMenu } from './components/DropdownMenu/DropdownMenu';
export { NavigationBar } from './components/NavigationBar/NavigationBar';
export { RadioButton } from './components/RadioButton/RadioButton';
export { RadioButtonGroup } from './components/RadioButton/RadioButtonGroup';
export { RoundButton } from './components/RoundButton/RoundButton';
export { RoundLinkButton } from './components/RoundLinkButton/RoundLinkButton';

0 comments on commit 25cc2ff

Please sign in to comment.