-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #95 from MetroStar/comet-ui-toggle-comp
comet-ui-toggle-comp # added toggle component to comet
- Loading branch information
Showing
6 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { default as DataTable } from './data-table'; | ||
export { default as Spinner } from './spinner'; | ||
export { default as Tabs, TabPanel } from './tabs'; | ||
export { default as Toggle } from './toggle'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './toggle'; |
35 changes: 35 additions & 0 deletions
35
packages/comet-extras/src/components/toggle/toggle.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from 'react'; | ||
import { Meta, StoryFn } from '@storybook/react'; | ||
import Toggle, { ToggleProps } from './toggle'; | ||
|
||
export default { | ||
title: 'Extras/Toggle', | ||
component: Toggle, | ||
argTypes: { | ||
id: { control: 'text' }, | ||
name: { control: 'text' }, | ||
checked: { control: 'boolean' }, | ||
label: { control: 'text' }, | ||
ariaLabel: { control: 'text' }, | ||
onChange: { action: 'changed' }, | ||
}, | ||
} as Meta<ToggleProps>; | ||
|
||
const Template: StoryFn<ToggleProps> = (args) => <Toggle {...args} />; | ||
|
||
export const Default = Template.bind({}); | ||
Default.args = { | ||
id: 'toggle', | ||
name: 'toggle', | ||
checked: false, | ||
label: 'Toggle', | ||
ariaLabel: 'Toggle button', | ||
}; | ||
|
||
export const Checked = Template.bind({}); | ||
Checked.args = { | ||
...Default.args, | ||
checked: true, | ||
label: 'Checked Toggle', | ||
ariaLabel: 'Checked toggle button', | ||
}; |
59 changes: 59 additions & 0 deletions
59
packages/comet-extras/src/components/toggle/toggle.style.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* Path: packages/comet-extras/src/components/toggle/toggle.tsx */ | ||
.toggle { | ||
align-items: center; | ||
display: flex; | ||
} | ||
|
||
.toggle-body { | ||
background-color: #e6e6e6; | ||
border-radius: 9999px; | ||
box-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05); | ||
height: 1.5rem; | ||
width: 3rem; | ||
} | ||
|
||
.toggle-body.toggle-body-on { | ||
background-color: #005ea2; | ||
} | ||
.toggle .pos-rel { | ||
position: relative; | ||
} | ||
.toggle-dot { | ||
background-color: #ffffff; | ||
border: 1px solid #e6e6e6; | ||
border-radius: 9999px; | ||
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); | ||
position: absolute; | ||
height: 1.5rem; | ||
left: 0; | ||
top: 0; | ||
width: 1.5rem; | ||
|
||
&.ml-6 { | ||
margin-left: 1.5rem; | ||
} | ||
&.ml-0 { | ||
margin-left: 0; | ||
} | ||
} | ||
|
||
.toggle-label { | ||
align-items: center; | ||
cursor: pointer; | ||
display: flex; | ||
&.ml-3 { | ||
margin-left: 0.75rem; | ||
} | ||
} | ||
|
||
.toggle-sr-only { | ||
border-width: 0; | ||
clip: rect(0, 0, 0, 0); | ||
height: 1px; | ||
margin: -1px; | ||
overflow: hidden; | ||
padding: 0; | ||
position: absolute; | ||
white-space: nowrap; | ||
width: 1px; | ||
} |
37 changes: 37 additions & 0 deletions
37
packages/comet-extras/src/components/toggle/toggle.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react'; | ||
import { render, fireEvent, screen } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { axe } from 'jest-axe'; | ||
import { Toggle } from './toggle'; // Assuming the Toggle component is in the same directory | ||
|
||
describe('Toggle Component Tests', () => { | ||
test('should render with no accessibility violations', async () => { | ||
const { container } = render( | ||
<Toggle id="test-toggle" label="Test toggle" onChange={jest.fn()} />, | ||
); | ||
expect(await axe(container)).toHaveNoViolations(); | ||
}); | ||
// Test to check if the Toggle renders correctly | ||
test('renders the Toggle component', () => { | ||
render(<Toggle id="test-toggle" />); | ||
|
||
expect(screen.getByRole('checkbox')).toBeInTheDocument(); | ||
}); | ||
|
||
// Test to check if onChange is called and state changes on click | ||
test('calls onChange and changes state when clicked', () => { | ||
const handleChange = jest.fn(); | ||
render(<Toggle id="test-toggle" onChange={handleChange} />); | ||
const toggle = screen.getByRole('checkbox'); | ||
fireEvent.click(toggle); | ||
expect(handleChange).toHaveBeenCalledTimes(1); | ||
expect(toggle).toBeChecked(); | ||
}); | ||
|
||
// Test to check if optional props like label are rendered correctly | ||
test('renders label correctly when provided', () => { | ||
const testLabel = 'Test Label'; | ||
render(<Toggle id="test-toggle" label={testLabel} />); | ||
expect(screen.getByText(testLabel)).toBeInTheDocument(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import './toggle.style.css'; | ||
import React, { ChangeEvent, ChangeEventHandler, useEffect, useState } from 'react'; | ||
|
||
export interface ToggleProps { | ||
/** | ||
* The unique identifier for this component | ||
*/ | ||
id: string; | ||
/** | ||
* The name of the text input | ||
*/ | ||
name?: string; | ||
/** | ||
* Whether the toggle is checked or not | ||
*/ | ||
checked?: boolean; | ||
/** | ||
* A label to display with the toggle | ||
*/ | ||
label?: string; | ||
/** | ||
* An accessible label for the toggle | ||
*/ | ||
ariaLabel?: string; | ||
/** | ||
* Custom callback for when input is changed | ||
*/ | ||
onChange?: ChangeEventHandler<HTMLInputElement>; | ||
} | ||
|
||
export const Toggle = ({ | ||
id, | ||
name, | ||
checked = false, | ||
label, | ||
ariaLabel, | ||
onChange, | ||
}: ToggleProps): React.ReactElement => { | ||
const [isChecked, setIsChecked] = useState(false); | ||
const toggleHandler = (event: ChangeEvent<HTMLInputElement>): void => { | ||
setIsChecked(!isChecked); | ||
onChange?.(event); | ||
}; | ||
|
||
useEffect(() => { | ||
setIsChecked(checked); | ||
}, [checked]); | ||
|
||
return ( | ||
<div className="toggle"> | ||
<label htmlFor={id} className="toggle-label" tabIndex={0} aria-label={ariaLabel}> | ||
<div className="pos-rel"> | ||
<input | ||
type="checkbox" | ||
id={id} | ||
name={name} | ||
className="toggle-sr-only" | ||
checked={isChecked} | ||
onChange={toggleHandler} | ||
tabIndex={-1} | ||
/> | ||
<div className={`toggle-body ${isChecked ? 'toggle-body-on' : ''}`}></div> | ||
<div className={`toggle-dot ${isChecked ? 'ml-6' : 'ml-0'}`}></div> | ||
</div> | ||
{label && <span className="toggle-label ml-3">{label}</span>} | ||
</label> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Toggle; |