Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed switch component styles #2928

Merged
merged 5 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 51 additions & 69 deletions src/design-system/components/switch/Switch.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
@use '~scss/utilities' as *;
@use 'sass:list';
$sizes: (
sm: (
45,
21,
15,
$border-width-sm
),
md: (
60,
28,
20,
$border-width-md
),
lg: (
75,
35,
25,
$border-width-lg - 1.5
)
);

@mixin track-mixin($width, $border-width) {
position: absolute;
Expand All @@ -9,6 +30,10 @@
transition:
background-color 0.3s ease,
border-color 0.3s ease;

.Mui-disabled & {
border-color: $blue-gray-100 !important;
}
}

@mixin thumb-mixin($diameter) {
Expand Down Expand Up @@ -44,64 +69,31 @@
overflow: visible;
padding: 0;
margin: 5px;

&:hover {
.MuiSwitch-track {
border-color: $blue-gray-500;

&.Mui-disabled {
border-color: $blue-gray-100 !important;
}
}
}
}

.#{$prefix}switch {
&--sm {
@include root-mixin(45, 21);

.MuiSwitch-thumb {
@include thumb-mixin(15);
}
@each $size, $values in $sizes {
&--#{$size} {
@include root-mixin(list.nth($values, 1), list.nth($values, 2));

.MuiSwitch-track {
@include track-mixin(45, $border-width-sm);
}

.MuiSwitch-switchBase {
@include switch-base-mixin(47, 15);
}
}

&--md {
@include root-mixin(60, 28);

.MuiSwitch-thumb {
@include thumb-mixin(20);
}

.MuiSwitch-track {
@include track-mixin(60, $border-width-md);
}

.MuiSwitch-switchBase {
@include switch-base-mixin(64, 20);
}
}

&--lg {
@include root-mixin(75, 35);
&:not(.Mui-disabled):hover .MuiSwitch-track {
border-color: $blue-gray-500;
}

.MuiSwitch-thumb {
@include thumb-mixin(25);
}
.MuiSwitch-thumb {
@include thumb-mixin(list.nth($values, 3));
}

.MuiSwitch-track {
@include track-mixin(75, $border-width-md);
}
.MuiSwitch-track {
@include track-mixin(list.nth($values, 1), list.nth($values, 4));
}

.MuiSwitch-switchBase {
@include switch-base-mixin(81, 25);
.MuiSwitch-switchBase {
@include switch-base-mixin(
list.nth($values, 1) + 2,
list.nth($values, 3)
);
}
}
}
}
Expand All @@ -112,24 +104,14 @@
gap: 10px;
overflow: visible;

&--sm {
.MuiFormControlLabel-label {
color: $body-text-color;
font-size: $font-size-sm !important;
}
}

&--md {
.MuiFormControlLabel-label {
color: $body-text-color;
font-size: $font-size-md !important;
}
}

&--lg {
.MuiFormControlLabel-label {
color: $body-text-color;
font-size: $font-size-lg !important;
@each $size,
$font-size in (sm: $font-size-sm, md: $font-size-md, lg: $font-size-lg)
{
&--#{$size} {
.MuiFormControlLabel-label {
color: $body-text-color;
font-size: $font-size !important;
}
}
}
}
14 changes: 12 additions & 2 deletions src/design-system/components/switch/Switch.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Switch, { SwitchProps } from '@mui/material/Switch'
import { FormControlLabel } from '@mui/material'
import { CircularProgress, FormControlLabel } from '@mui/material'
import './Switch.scss'
interface AppSwitchProps extends Omit<SwitchProps, 'size'> {
labelPosition?: 'start' | 'end' | 'top' | 'bottom'
Expand All @@ -15,7 +15,17 @@ export const AppSwitch = ({
disabled,
...props
}: AppSwitchProps) => {
return (
const loaderSizes = {
sm: 21,
md: 28,
lg: 35
}
const loader = (
<CircularProgress data-testid='loader' size={loaderSizes[size]} />
)
return loading ? (
loader
) : (
<FormControlLabel
className={`s2s-form-label-box s2s-form-label-box--${size}`}
control={
Expand Down
92 changes: 37 additions & 55 deletions tests/unit/design-system/components/Switch/Switch.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { render, screen } from '@testing-library/react'
import { fireEvent } from '@testing-library/react'
import {AppSwitch} from '~/design-system/components/switch/Switch'
import { AppSwitch } from '~/design-system/components/switch/Switch'

describe('AppSwitch Component', () => {
it('renders correctly with default props', () => {
render(<AppSwitch />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
expect(switchEl).not.toBeDisabled()
})

it('triggers `onChange` when toggled', () => {
it('calls `onChange` when toggled', () => {
const handleChange = vi.fn()
render(<AppSwitch onChange={handleChange} />)

Expand All @@ -20,74 +21,55 @@ describe('AppSwitch Component', () => {
expect(handleChange).toHaveBeenCalledTimes(1)
})

it('displays the label when provided', () => {
render(<AppSwitch label='Test Label' />)
it('renders label when provided', () => {
render(<AppSwitch label="Test Label" />)

const labelEl = screen.getByText('Test Label')
expect(labelEl).toBeInTheDocument()
})

it('applies the correct Large size style', () => {
render(<AppSwitch size='lg' />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
})

it('applies the correct Medium size style', () => {
render(<AppSwitch size='md' />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
})

it('applies the correct Small size style', () => {
render(<AppSwitch size='sm' />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
})
describe('Size classes', () => {
it.each([
['lg', 's2s-switch--lg'],
['md', 's2s-switch--md'],
['sm', 's2s-switch--sm'],
])('applies the correct class for size: %s', (size, expectedClass) => {
render(<AppSwitch size={size} />)
const switchWrapper = screen.getByRole('checkbox').closest('.s2s-switch--lg, .s2s-switch--md, .s2s-switch--sm')

expect(switchWrapper).toHaveClass(expectedClass)
})
})

it('is disabled when loading is true', () => {
render(<AppSwitch loading />)
const loaderEl = screen.getByTestId('loader')

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeDisabled()
expect(loaderEl).toBeInTheDocument()
expect(screen.queryByRole('checkbox')).not.toBeInTheDocument()
})

it('is disabled when disabled prop is true', () => {
render(<AppSwitch disabled />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeDisabled()
})

it('renders the label in the correct end position', () => {
render(<AppSwitch label="End Label" labelPosition='end' />)

const labelEl = screen.getByText('End Label')
expect(labelEl).toBeInTheDocument()
})

it('renders the label in the correct start position', () => {
render(<AppSwitch label="Start Label" labelPosition='start' />)

const labelEl = screen.getByText('Start Label')
expect(labelEl).toBeInTheDocument()
})

it('renders the label in the correct top position', () => {
render(<AppSwitch label="Top Label" labelPosition='top' />)

const labelEl = screen.getByText('Top Label')
expect(labelEl).toBeInTheDocument()
expect(switchEl).toBeDisabled()
})

it('renders the label in the correct bottom position', () => {
render(<AppSwitch label="Bottom Label" labelPosition='bottom' />)

const labelEl = screen.getByText('Bottom Label')
expect(labelEl).toBeInTheDocument()
describe('Label position', () => {
it.each([
['end', 'End Label'],
['start', 'Start Label'],
['top', 'Top Label'],
['bottom', 'Bottom Label'],
])(
'renders label in correct position: %s',
(position, label) => {
render(<AppSwitch label={label} labelPosition={position} />)
const labelEl = screen.getByText(label)

expect(labelEl).toBeInTheDocument()
}
)
})

})
})
Loading